diff --git a/app/Models/Application.php b/app/Models/Application.php index 8c575eb841..02c6d0935b 100644 --- a/app/Models/Application.php +++ b/app/Models/Application.php @@ -2132,7 +2132,7 @@ class Application extends BaseModel continue; } if ($source->startsWith('.')) { - $source = str($workdir.$source->after('.')); + $source = replaceLocalSource($source, str($workdir)); } $mkdirCommand = rawComposeBindMkdirCommand($source->value()); if ($mkdirCommand !== null) { diff --git a/tests/Unit/RawComposeVolumePathTest.php b/tests/Unit/RawComposeVolumePathTest.php index 685f84d84f..ec30253f58 100644 --- a/tests/Unit/RawComposeVolumePathTest.php +++ b/tests/Unit/RawComposeVolumePathTest.php @@ -246,3 +246,14 @@ YAML); expect($application->docker_compose_raw)->toContain('appdata'); }); + +it('resolves parent directory segments in long-form bind sources before remote work', function () { + Process::fake(); + + $application = makeRawComposeApplication(rawComposeBindSource('../../../../../../outside')); + + expect(fn () => $application->oldRawParser()) + ->toThrow(Exception::class, 'resolves to a path above /'); + + Process::assertNothingRan(); +});