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

add extra $path validation to TenantAssetsController

This commit is contained in:
Samuel Štancl 2023-08-24 18:21:23 +02:00
parent 395192442d
commit 4af70d302f
3 changed files with 31 additions and 1 deletions

1
.gitignore vendored
View file

@ -10,3 +10,4 @@ coverage/
clover.xml clover.xml
tests/Etc/tmp/queuetest.json tests/Etc/tmp/queuetest.json
docker-compose.override.yml docker-compose.override.yml
.DS_Store

View file

@ -18,7 +18,7 @@ class TenantAssetsController extends Controller
public function asset($path = null) public function asset($path = null)
{ {
abort_if($path === null, 404); $this->validatePath($path);
try { try {
return response()->file(storage_path("app/public/$path")); return response()->file(storage_path("app/public/$path"));
@ -26,4 +26,20 @@ class TenantAssetsController extends Controller
abort(404); abort(404);
} }
} }
/**
* @throws \Symfony\Component\HttpKernel\Exception\HttpException
*/
protected function validatePath(string|null $path): void
{
abort_if($path === null, 404);
$allowedRoot = storage_path('app/public');
// Prevent path traversal attacks. This is generally a non-issue on modern
// webservers but it's still worth handling on the application level as well.
if (! str(realpath("{$allowedRoot}/{$path}"))->startsWith($allowedRoot)) {
abort(403);
}
}
} }

View file

@ -141,4 +141,17 @@ class TenantAssetTest extends TestCase
$response->assertNotFound(); $response->assertNotFound();
} }
public function test_asset_controller_returns_a_403_when_an_invalid_path_is_provided()
{
TenantAssetsController::$tenancyMiddleware = InitializeTenancyByRequestData::class;
$tenant = Tenant::create();
tenancy()->initialize($tenant);
$response = $this->get(tenant_asset('../foo.txt'), [
'X-Tenant' => $tenant->id,
]);
$response->assertForbidden();
}
} }