2010-06-01 13 views
5

Questa potrebbe essere una domanda stupida. O forse le mie capacità di hacking sono limitate (non le prendo affatto).Le query multilinea sql-injection sono sicure?

Ho una domanda che assomiglia a questo:

<?php 
$query =<<<eot 
    SELECT  table_x.field1, 
       table_x.field2, 
       table_y.*, 
       table_z.field4 
    FROM  (
        SELECT ... 
       ) as table_y 
    LEFT JOIN table_x 
    ON   table_x.field1 = table_y.field_x 
    LEFT JOIN table_z 
    ON   table_z.field1 = table_y.field_z 
    WHERE  table_x.field3 = '$something' 
    AND   table_z.field4 = '1' 
    AND   table_z.field5 = '2' 
eot; 
?> 

Ho un sacco di altri test su $something prima che venga utilizzato, come $something = explode(' ',$something); (che poi il risultato in una stringa) nessuno di loro ha intenzione di evitare che iniezione ma rendono difficile per l'iniezione data ottenere come è per la query effettiva. Tuttavia, ci sono modi. Sappiamo tutti quanto sia facile sostituire uno spazio per qualcos'altro che è ancora valido ..

Quindi, non è davvero un problema rendere un potenziale punto di copertura SQL dannoso che $something ... Ma c'è qualche modo di commentare il resto della stringa di query originale se è multi-linea?

posso commentare AND table_z.field4 = '1' utilizzando ;-- ma non posso commentare il seguente AND table_z.field5 = '2'

E 'possibile aprire un commento su più righe /* senza chiudere o qualcosa che sembrava, e quindi consentire l'iniezione di ignorare il multi- query di riga?

risposta

4

Non è sicuro. Anche se non può commentare il resto, potrebbe precederlo con SELECT * FROM my_table WHERE 1 = 1.

+0

Grazie Adam, hai ragione. È facile hackerare questa query su più righe. Vergognatevi per non aver visto questa opzione. Questo è comunque un esempio e la mia situazione è un po 'più complicata. Poiché non sono riuscito a spiegarmi, accetterò la tua risposta come corretta. – acm

5
$something = "'; DROP TABLE table_x; SELECT * FROM table_z WHERE '1' = '1"; 
2

Usa preparato istruzioni per essere sicuri:

http://www.php.net/manual/en/pdo.prepare.php

String interpolazione è sempre il rischio di iniezione di codice se l'ingresso non è sufficientemente pulito.

La rimozione della possibilità di eseguire codice arbitrario è il modo più facile e molto più sicuro.

+0

+1 Questa è davvero l'unica risposta corretta. "Pulire" te stesso è buono quanto la tua conoscenza dell'iniezione SQL. Lascia che il database/testato ORM lo gestisca per te. – richsage

2

@Techpriester: non è quello che è una dichiarazione preparata.

http://dev.mysql.com/tech-resources/articles/4.1/prepared-statements.html (vecchia versione, la stessa cosa)

DOP è un livello di astrazione database che "si prepara dichiarazioni", ma una dichiarazione preparata è qualcosa di completamente diverso!

+1

PDO emula le istruzioni preparate per impostazione predefinita, ma è possibile disattivare questa modalità '$ pdo-> setAttribute (PDO :: ATTR_EMULATE_PREPARES, false);' Guarda il tuo log di query generale MySQL e guardalo funzionare! –