Skip to content

Commit 0c105a2

Browse files
fix: validate build cache keys
1 parent f4a7374 commit 0c105a2

2 files changed

Lines changed: 28 additions & 1 deletion

File tree

src/Executor/Runner/Docker.php

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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)) {

tests/unit/Executor/Runner/DockerTest.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,15 @@ public function testNoCacheLifecycleShellCommandsAreGenerated(): void
4444
$this->assertStringNotContainsString('build-cache-save.sh', $command);
4545
}
4646

47+
public function testInvalidBuildCacheKeyIsRejected(): void
48+
{
49+
$this->expectException(\Exception::class);
50+
$this->expectExceptionCode(400);
51+
52+
$method = new ReflectionMethod(Docker::class, 'validateBuildCacheKey');
53+
$method->invoke($this->createDocker(), '..');
54+
}
55+
4756
/**
4857
* @return string[]
4958
*/

0 commit comments

Comments
 (0)