1
0
Fork 0
mirror of https://github.com/archtechx/tenancy.git synced 2026-09-20 11:14:03 +00:00

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.
This commit is contained in:
lukinovec 2026-08-18 17:13:29 +02:00 committed by Samuel Stancl
parent a9cdeb220b
commit ff3a2a3e2c

View file

@ -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]);