From 7363318f6e198b04853f6b74200eb73b2bc66fa9 Mon Sep 17 00:00:00 2001 From: lukinovec Date: Fri, 1 May 2026 13:09:37 +0200 Subject: [PATCH] Make in-memory DB detection more strict In-memory DBs have to start with "file:_tenancy_inmemory_". This prevents path traversal. --- .../TenantDatabaseManagers/SQLiteDatabaseManager.php | 2 +- tests/TenantDatabaseManagerTest.php | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Database/TenantDatabaseManagers/SQLiteDatabaseManager.php b/src/Database/TenantDatabaseManagers/SQLiteDatabaseManager.php index c2c55d87..9df56ccb 100644 --- a/src/Database/TenantDatabaseManagers/SQLiteDatabaseManager.php +++ b/src/Database/TenantDatabaseManagers/SQLiteDatabaseManager.php @@ -155,6 +155,6 @@ class SQLiteDatabaseManager implements TenantDatabaseManager public static function isInMemory(string $name): bool { - return $name === ':memory:' || str_contains($name, '_tenancy_inmemory_'); + return $name === ':memory:' || str_starts_with($name, 'file:_tenancy_inmemory_'); } } diff --git a/tests/TenantDatabaseManagerTest.php b/tests/TenantDatabaseManagerTest.php index dfceb48a..0a51bd1d 100644 --- a/tests/TenantDatabaseManagerTest.php +++ b/tests/TenantDatabaseManagerTest.php @@ -615,7 +615,7 @@ test('database managers validate parameters that cannot be bound', function ($dr } })->with('database_managers'); -test('sqlite database manager validates database filenames', function () { +test('sqlite database manager validates database names', function () { $manager = app(SQLiteDatabaseManager::class); // Dots are allowed in database names @@ -630,9 +630,13 @@ test('sqlite database manager validates database filenames', function () { expect(fn () => $manager->databaseExists('')) ->toThrow(InvalidArgumentException::class); - // In-memory database names aren't validated - expect(fn () => $manager->databaseExists('../_tenancy_inmemory_')) + // In-memory database names have to start with 'file:_tenancy_inmemory_' + expect(fn () => $manager->databaseExists('file:_tenancy_inmemory_123?mode=memory&cache=shared')) ->not()->toThrow(InvalidArgumentException::class); + + // Doesn't start with 'file:_tenancy_inmemory_', not considered an in-memory database, filename validation applies + expect(fn () => $manager->databaseExists('../_tenancy_inmemory_')) + ->toThrow(InvalidArgumentException::class); }); // Datasets