@@ -256,6 +256,7 @@ public function createRuntime(
256256 /** @var array<string, mixed> $container */
257257 $ container = [];
258258 $ output = [];
259+ $ cacheWarnings = [];
259260 $ startTime = \microtime (true );
260261
261262 $ runtime = new Runtime (
@@ -329,8 +330,9 @@ public function createRuntime(
329330 ];
330331
331332 $ cacheEnabled = $ cacheKey !== '' && $ command !== '' && $ command !== '0 ' ;
332- $ cacheWarnings = [];
333333 if ($ cacheEnabled ) {
334+ $ this ->validateBuildCacheKey ($ cacheKey );
335+
334336 try {
335337 $ this ->restoreBuildCacheArtifact ($ cacheKey , $ tmpCache , $ localDevice );
336338 } catch (Throwable $ err ) {
@@ -487,6 +489,10 @@ public function createRuntime(
487489 ]];
488490 }
489491
492+ if ($ cacheWarnings !== []) {
493+ $ output = \array_merge ($ cacheWarnings , $ output );
494+ }
495+
490496 if ($ remove ) {
491497 \sleep (2 ); // Allow time to read logs
492498 }
@@ -561,6 +567,18 @@ private function getBuildCacheWarning(string $message): array
561567 ];
562568 }
563569
570+ private function validateBuildCacheKey (string $ cacheKey ): void
571+ {
572+ if (
573+ \str_contains ($ cacheKey , "\0" ) ||
574+ \str_starts_with ($ cacheKey , '/ ' ) ||
575+ \str_contains ($ cacheKey , '\\' ) ||
576+ \preg_match ('#(^|/)\.\.(?:/|$)# ' , $ cacheKey ) === 1
577+ ) {
578+ throw new \Exception ('Invalid build cache key ' , 400 );
579+ }
580+ }
581+
564582 private function restoreBuildCacheArtifact (string $ cacheKey , string $ tmpCache , Local $ localDevice ): void
565583 {
566584 if (!$ localDevice ->createDirectory ($ tmpCache )) {
0 commit comments