Home > Apache, Webserver, MySQL, DB Server, Opensource World, PHP il turbo nel web > Potenziale SQL Injection con AdoDB e driver mysqli

Potenziale SQL Injection con AdoDB e driver mysqli

[SEGNALO CHE HO SCOPERTO QUESTA COSA DA POCO E LIMITANDOMI AD ALCUNI TEST E PROVE VELOCI MA REALI, PERCUI OGNI EVENTUALE APPROFONDIMENTO/SMENTITA ETC... E' BEN ACCETTO]

Segnalo una problematica di sicurezza abbastanza importante per coloro che utilizzano adodb utilizzando il driver mysqli (le nuove funzioni di connessione con mysql native in php 5).

In sostanza le nuove funzioni mysqli consentono mediante la seguente funzione: mysqli_multi_query di poter eseguire più statement SQL in mysql come ad esempio:

SELECT * FROM TBL1 WHERE id = 1; DROP table TBL2;

Questa query utilizzando le vecchie librerie mysql (es. mysql_connect) dava errore.
La possibilità di eseguire più query SQL è supportata su mysql 5.0.x anche da command line, non saprei se anche vecchie versioni lo consentivano.

Questo significa che se per esempio utilizziamo in php una query del tipo:

$sql = “SELECT * FROM tbl1 WHERE id = $_GET['id']“; // (Premesso che venga come minimo fatto l’escape dei caratteri come ‘ o “)

Possiamo rischiare che qualche burlone passi in GET il seguente valore:
“1; DROP TABLE tbl2;”
Il che comporterebbe che l’SQL eseguito sia:

SELECT * FROM TBL1; DROP table TBL2;

Di fatto quindi con AdoDB con driver mysqli, la seconda query viene effettivamente eseguita.

Diventa quindi essenziale fare un controllo sull’input dell’utente per $_GET['id']. Ad esempio verificando che sia un numero intero.

La soluzione più rapida è quella di cambiare la connect di AdoDB dicendogli di usare il driver mysql anziché mysqli, la soluzione migliore e da fare comunque resta in ogni caso il filtraggio di tutti i dati in input.

Share
  1. 30 December 2008 a 22:19 | #1

    Aggiungo che facendo qualche test, se al posto di utilizzare la sintassi:

    $sql = “SELECT * FROM tbl1 WHERE id = “.$_GET['id'];

    Usiamo:

    $sql = “SELECT * FROM tbl1 WHERE id = “‘”.$_GET['id'].”‘”;

    Facendo un corretto escape di ‘ e ” di fatto evitiamo che il ; e la restante parte di SQL vengano interpretati come statement SQL ma semplicemente finiranno per essere considerati facenti parte della stringa di ricerca nel campo di id e la query non darà risultati o alla peggio, fallirà.

    Resta comunque inteso che fare controlli di formalità resta senza dubbio la migliore soluzione.

  2. 29 March 2012 a 9:31 | #2

    Penso che fare l’escaping di ogni stringa che provenga dai dati in input (GET/POST) sia sempre la base di ogni buon programmatore.
    Personalmente preferisco sempre evitare il multi quering e usare binding e prepare dopo aver filtrato i dati in ingresso proprio per evitare le injection a prescindere da ciò che hai scoperto tu; cosa che comunque rimane valida.

    M.

  3. 30 March 2012 a 11:33 | #3

    @Marco Grazia
    Si, verissimo, anche se ultimamente ove possibile (ma non con php) utilizzo ORM che si smazzano da soli queste problematiche ormai un po’ trite, ritrite e noiose (ma sempre pericolose).

    Ciao, Max

  1. 30 December 2008 a 6:02 | #1