Skip to content

Commit

Permalink
🔒 Make sure that the catalog name cannot be used for an SQL injection
Browse files Browse the repository at this point in the history
  • Loading branch information
fblaser committed Mar 18, 2024
1 parent 228f6d2 commit d16a3d9
Showing 1 changed file with 16 additions and 3 deletions.
19 changes: 16 additions & 3 deletions src/Catalog.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@ class Catalog
*/
private $connection;

// Prepared statements with the USE CATALOG command are not working as expected.
// This method is used to check the catalog name before using it in a query.
private function checkCatalogName($catalogName): void
{
if (preg_match('/[^a-zA-Z0-9_]/', $catalogName) === 1)
{
throw new Exception('Invalid catalog name');
}
}

// This is too low, because this is a beta version we are developing for.
public const MINIMAL_MARIA_VERSION = '11.0.2';

Expand Down Expand Up @@ -101,6 +111,7 @@ public function create(string $catName): int
__DIR__ . '/create_catalog_sql/maria_add_gis_sp.sql',
__DIR__ . '/create_catalog_sql/mysql_sys_schema.sql',
];
$this->checkCatalogName($catName);
$this->connection->exec('CREATE CATALOG IF NOT EXISTS ' . $catName);
$this->connection->exec('USE CATALOG ' . $catName);

Expand Down Expand Up @@ -185,13 +196,14 @@ public function drop(string $catName): bool
{
try {
// Enter the catalog.
$this->checkCatalogName($catName);
$this->connection->exec('USE CATALOG ' . $catName);

// Check if there are any tables besides mysql, sys, performance_schema and information_schema.
$tables = $this->connection->query('SHOW DATABASES');
foreach ($tables as $table) {
if (in_array($table['Database'], ['mysql', 'sys', 'performance_schema', 'information_schema']) === false) {
throw new \Exception('Catalog is not empty');
throw new Exception('Catalog is not empty');
}
}

Expand All @@ -201,9 +213,9 @@ public function drop(string $catName): bool
$this->connection->exec('DROP DATABASE IF EXISTS performance_schema');

// Drop the catalog.
$this->connection->exec('DROP CATALOG ' . $catName);
$this->connection->exec('DROP CATALOG '. $catName);
} catch (\PDOException $e) {
throw new \Exception('Error dropping catalog: ' . $e->getMessage());
throw new Exception('Error dropping catalog: ' . $e->getMessage());
}

return true;
Expand Down Expand Up @@ -239,6 +251,7 @@ public function createAdminUserForCatalog(
string $password,
string $authHost = 'localhost'
): void {
$this->checkCatalogName($catalog);
$this->connection->exec("USE CATALOG {$catalog}");
$this->connection->exec("USE mysql");

Expand Down

0 comments on commit d16a3d9

Please sign in to comment.