From ff3a2a3e2c508accf343892e30ce88ee025bfdd6 Mon Sep 17 00:00:00 2001 From: lukinovec Date: Tue, 18 Aug 2026 17:13:29 +0200 Subject: [PATCH] Assert that the tenant asset controller only serves files inside the configured disk's root (regression test) Currently this fails because the controller checks that the requested file is inside the asset root using a plain string prefix, so with the root set to '%storage_path%/app/media/', a request for '../media-originals/photo.jpg' is served from the sibling 'app/media-originals' directory. --- tests/TenantAssetTest.php | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tests/TenantAssetTest.php b/tests/TenantAssetTest.php index 7f1b9ab0..3bd501de 100644 --- a/tests/TenantAssetTest.php +++ b/tests/TenantAssetTest.php @@ -298,6 +298,34 @@ test('tenant asset controller returns a 404 when accessing a nonexistent file', ]); }); +test('tenant asset controller throws an exception when accessing a file in a directory whose name starts with the name of the asset root', function () { + config([ + 'tenancy.identification.default_middleware' => InitializeTenancyByRequestData::class, + // Disk used for serving the assets -- its root is 'app/media' in the tenant's storage directory + 'filesystems.disks.media' => ['driver' => 'local', 'root' => storage_path('app/media')], + 'tenancy.filesystem.disks' => array_merge(config('tenancy.filesystem.disks'), ['media']), + 'tenancy.filesystem.root_override.media' => '%storage_path%/app/media/', + ]); + + TenantAssetController::$publicDisk = 'media'; + + $tenant = Tenant::create(); + tenancy()->initialize($tenant); + + Storage::disk('media')->put('photo.jpg', 'public file'); + + // A directory next to the asset root, e.g. one holding files that shouldn't be served + mkdir($privateDirectory = storage_path('app/media-originals'), recursive: true); + file_put_contents($privateDirectory . '/photo.jpg', 'private file'); + + $this->withoutExceptionHandling(); + pest()->expectExceptionMessage('Accessing a file outside the storage root'); // outside tests this is a 404 + + pest()->get(tenant_asset('../media-originals/photo.jpg'), [ + 'X-Tenant' => $tenant->id, + ]); +}); + test('test asset controller returns a 404 when accessing a file outside the storage root', function () { config(['tenancy.identification.default_middleware' => InitializeTenancyByRequestData::class]);