2012-06-16 14 views
5

Pracuję nad automatyzacją wdrożenia napisanego przeze mnie oprogramowania i muszę mieć możliwość generowania nowych baz danych mysql dla nowych kont. Mam jednak obawy, jeśli chodzi o dezynfekcję danych wejściowych.Tworzenie nowych baz danych z potencjalnie niebezpiecznych danych wejściowych za pośrednictwem PDO i mysql

Używam PDO; jednak najwyraźniej nie możesz użyć przygotowanych instrukcji z "CREATE DATABASE". Tak więc próbowałem również używać PDO :: quote; jednak moje nowo utworzone nazwy baz danych są otoczone pojedynczymi cudzysłowami (nie koniec świata, ale nadal chciałbym tego uniknąć).

Czy jest jakiś sposób, aby to działało z przygotowanymi oświadczeniami? Jeśli nie, co mogę zrobić, aby uchronić się przed atakiem sql injection? Moim jedynym pomysłem jest posiadanie dozwolonej białej listy dozwolonych postaci.

Dzięki!

+2

Biała lista jest prawdopodobnie najlepszym sposobem, aby przejść - także widząc jak niektóre silniki pamięci masowej MySQL będą tworzyć foldery i pliki zawierające nazwę bazy danych. –

Odpowiedz

2

musisz napisać stored procedure, do którego następnie możesz przekazać odkażone wejście (aby użyć mojego przykładu musisz zmienić niektóre zmienne, takie jak nazwa bazy danych, poprawny użytkownik i hasło, i takie, aby działać na bazie oczywiście)

przykład:

<?php 
$dsn = 'mysql:dbname=scratch;host=127.0.0.1'; 
$user = 'root'; 
$password = ''; 

try { 
    $dbh = new PDO($dsn, $user, $password); 
} catch (PDOException $e) { 
    echo 'Connection failed: ' . $e->getMessage(); 
} 

$dbname = 'brand_new_db'; 

$statement = $dbh->prepare("CALL dbcreator(:db)"); 
$statement->bindParam(':db',$dbname); 

if(!$statement->execute()){ 
    print_r($statement->errorInfo()); 
} 
else { 
    foreach($dbh->query('SHOW DATABASES')->fetchAll() as $row){ 
     print "$row[0]" . PHP_EOL; 
    } 
} 

procedury przechowywane:

DELIMITER $$ 

DROP PROCEDURE IF EXISTS `scratch`.`dbcreator` $$ 
CREATE DEFINER=`root`@`localhost` PROCEDURE `dbcreator`(IN dbname VARCHAR(64)) 
BEGIN 

SET @db = dbname; 
SET @statement = CONCAT('CREATE DATABASE ',@db); 
PREPARE prepared_statement FROM @statement; 
EXECUTE prepared_statement; 

END $$ 

DELIMITER ; 

Y Tworzymy instrukcję SQL do PREPARE, w naszym przypadku CREATE DATABASE <our database>;, ponieważ instrukcja CREATE DATABASE nie będzie działać ze zmienną, a następnie po prostu EXECUTE to. Na koniec wykonaj CALL dbcreator('<dbname>'), aby wykonać procedurę przechowywaną. Jest to CALL dbcreator(:dbname), do którego można używać i wiązać parametry.

Jak widać, w ten sposób można nadal wiązać swoje parametry bezpiecznie przez pdo podczas tworzenia bazy danych. Mimo to może nie być złym pomysłem przedrostowanie całej utworzonej bazy danych za pomocą krótkiego stałego łańcucha dla łatwego wyszukiwania i dyskryminacji. W procedurze przechowywanej dbname to limited to 64 characters, ponieważ jest to obecny limit mysql:

+0

Dzięki! To powinno wystarczyć. Nadal prawdopodobnie połączę to z białą listą ze względu na inne wymagania i odfiltrowuję śmieci, ale używanie przygotowanych stwierdzeń pozwala mi tylko trochę lepiej spać. – user1234814

Powiązane problemy