2010-06-14 17 views
10

Lo script è in PHP e come DB utilizzo MySQL. Ecco la sceneggiatura stessa.Questa query è sicura da SQL injection?

$unsafe_variable = $_GET["user-input"]; 
$sql=sprintf("INSERT INTO table (column) VALUES('%s')",$unsafe_variable); 
mysql_query($sql); 

Alcuni dicono che se l'utente assegna ;DROP TABLE blah; stringa alla variabile $ unsafe_variable si elimina la tabella.

Ma provato questo esempio,

http://localhost/test.php?user-input=DROP%20TABLE%20my_table 

Ma non eliminare la tabella invece inserita una nuova riga (;DROP TABLE blah;) nella tabella.

Qualcuno potrebbe spiegarmi come è possibile attaccare questo script con iniezioni SQL?

+3

'mysqli' o' PDO' e le loro dichiarazioni preparate sarebbe essere una scelta migliore – Powerlord

+0

Grazie mille per tutti i partecipanti alla domanda. Mi sono davvero reso conto che con solo 'sprintf' non possiamo essere sicuri che la nostra query sia al sicuro da ** sql-injection **. Per questo specifico esempio né io né i partecipanti potremmo presentare il modo in cui eseguire sql-injection. Ma ho trovato un buon esempio in SQL dove possiamo eseguire sql-injection anche se usiamo 'sprintf'. L'esempio sql può essere trovato [qui] (http://php.net/manual/en/function.mysql-real-escape-string.php "Manuale PHP online"). Vedere la sezione di "Esempio n. 2 Un esempio di attacco di iniezione SQL" – Bakhtiyor

risposta

13

Questa particolare iniezione non funzionava poiché la funzione mysql_query di PHP consente una sola query per chiamata. Tuttavia, possono funzionare se column ha una chiave primaria o univoca:

$unsafe_variable = "admin') ON DUPLICATE KEY UPDATE password=MD5(CONCAT('knownsalt', 'newpassword'))#"; 

meglio usare il prolisso mysql_real_escape_string funzione:

$sql=sprintf("INSERT INTO table (column) VALUES(%s)", 
      mysql_real_escape_string($unsafe_variable)); 
mysql_query($sql); 
4

mysql_query() non consente l'esecuzione di più query in una funzione. Quindi non puoi INSERIRE e poi DROP la tabella. Ma non dovresti fare affidamento su questo come 'sicurezza'. Utilizzare invece le query parametrizzate. Controlla la libreria di PHP PDO.

Tuttavia, potrebbero modificare qualsiasi altra cosa, ad esempio SELEZIONARE un campo password da un'altra tabella come subquery da inserire in quella tabella in modo che possano visualizzare l'hash.

+0

http://php.net/manual/en/function.mysql-query.php –

+0

Qualche motivo per downvote? Le dichiarazioni preparate sono generalmente più sicure di 'mysql_real_escape_string'. –

1

No, sprintf non sfugge alla fruizione dei contenuti:

$unsafe_variable = mysql_real_escape_string($_GET["user-input"]); 
$sql=sprintf("INSERT INTO table (column) VALUES('%s')",$unsafe_variable); 
mysql_query($sql); 
1
mysql_real_escape_string($unsafe_variable) 
3

Mentre mysql_query consente solo una query da eseguire, in generale, questa query non è sicuro. Un esempio di un ingresso pericoloso che sfruttare la ricerca è:

'); DROP TABLE my_table; -- 

Il '); all'inizio si chiuderà la ricerca e inserire un valore vuoto, ma consentirà di query aggiuntive da eseguire dopo dell'inserto. Quindi, dopo aver lasciato cadere un tavolo, lo -- alla fine segnerà tutto il resto successivo (ovvero il resto della query) come commento.

Per preparare in modo sicuro l'input da utilizzare in una query, utilizzare mysql_real_escape_string.

+0

Volevo dire che se eseguo questo script [http: //authoringtool/test.php? User-input = ');% 20DROP% 20TABLE% 20my_table2;% 20--] eliminerà my_table2 dal mio DB? In caso contrario, per favore dammi un esempio reale di come funziona, perché il tuo esempio non ha eliminato my_table2 :) – Bakhtiyor

+1

Come già detto, 'mysql_query' non supporta l'esecuzione di più query, ma dovresti comunque proteggere correttamente la query. –

1

Alcuni dicono che se l'utente assegna, DROP TABLE blah; stringa alla variabile $ unsafe_variable cancella la tabella.

Questo non è il caso, ma se non si capisce il motivo, non si può sapere se il codice è sicuro. Hai intenzione di postare ogni riga qui per verificare se è sicuro?

Senza una lunga spiegazione su cosa sta facendo il codice sopra e su come comprometterlo (SQL injection è già ben documentato altrove - prova Google per iniziare) dovresti SEMPRE assicurarti che tutti i dati che escono dal tuo codice PHP siano SEMPRE nella corretta rappresentazione di dove sta andando.

Per un database MySQL che si intende:

1) utilizzare l'uscita di mysql_real_escape_string (e assicurarsi che si passa il diritto maniglia risorse)

o

2) utilizzare vincolante parametro.

Una discussione corretta sugli attacchi di iniezione di codice potrebbe facilmente riempire diverse centinaia di pagine, un po 'troppo per rispondere in un S.O. query.

C.

0

Penso che l'esempio si avrebbe bisogno di provare è http://localhost/test.php?user-input=';DROP%20TABLE%20my_table'

il '); chiude il segmento values('%s, e poi emette un nuovo comando, drop table...

+0

Questo non funziona. – Bakhtiyor

2

L'unico modo si dovrebbe essere gestire variabili non sicure è con i parametri di bind.

Leggere da bobby-tables.com.