Le citazioni di escape mi proteggono dall'iniezione SQL?

3

Una domanda per principianti qui.

Ho appena letto una breve introduzione all'iniezione SQL su link

Si dice di trovare un percorso di richiesta GET sull'applicazione PHP per vedere se è vulnerabile o meno.

Ho un sito web con il seguente URL di query.

http://example.com/get_stuff?query=hello&limit=50&offset=0

Sto utilizzando una query non elaborata, quindi, in base al sito, presumo che il mio sito Web sia vulnerabile all'iniezione SQL.

Per provarlo, ci provo.

http://example.com/get_stuff?query=hello&limit=50'&offset=0

(aggiungendo una virgoletta singola dopo il limite = 50)

Questo errore viene stampato - come previsto e come suggerito dal sito Web - il che significa che la mia query è vulnerabile.

Ora, per proteggerlo, voglio assicurarmi di "sfuggire" alle virgolette nelle mie domande. Sto usando un framework PHP chiamato CodeIgniter, in cui esiste una funzione chiamata $this->db->escape() .

Quindi uso questa funzione "escape" sul valore 50, ma ora restituisce un errore dicendo che "50" non è un numero intero valido.

Giusto, la condizione "LIMIT" dovrebbe ricevere solo un valore intero.

Ma la mia domanda è: la mia query ora è "SQL-injection" sicura?

    
posta ericbae 08.05.2013 - 02:07
fonte

4 risposte

5

La tua query è un'iniezione del primo ordine, forse-solo-forse-sicura, a seconda di come CodeIgniter è migliorato dall'ultima volta che l'ho usato.

Siamo chiari su questo: nessuna sanitizzazione ti impedirà di eseguire l'iniezione SQL. La vera "soluzione migliore" per PHP è la parametrizzazione, che consente di estrarre le variabili dalla query. In caso contrario, tuttavia, una corretta sanitizzazione può essere d'aiuto. L'ultima volta che ho controllato (tre anni fa), CodeIgniter ha utilizzato mysql_real_escape_string che, sebbene sia un valido deterrente per la maggior parte degli script kiddies, non fermerà un hacker esperto.

La cosa migliore da fare è leggere come CodeIgniter esegue effettivamente la sanitizzazione / parametrizzazione. Se è solo addslashes , evitalo come la peste. Esistono molti altri modi per eseguire le iniezioni SQL, ad esempio, è possibile jukeing la codifica dei caratteri per passare le virgolette attraverso la maggior parte delle configurazioni addslashes / mysql_escape_string . Ci sono un sacco di tutorial in materia.

    
risposta data 08.05.2013 - 02:14
fonte
5

No, le citazioni di escape / le virgolette doppie non garantiscono che la tua applicazione web non sia vulnerabile. Dipende anche dalle query SQL che hai usato. Ho già visto molti esempi con le funzioni addslashes() e escape() -like in cui le persone apprezzano questo:

SELECT * FROM a WHERE id > addslashes(user_input)

Questo è ovviamente vulnerabile, perché non è necessario un solo apice / virgolette per eseguire SQL Injection. È bene ricordare che, in casi rari, addslashes potrebbe scavalcato [ 1] .

La soluzione più consigliata per il tuo problema SQL-Injection è dimenticare la concatenazione delle stringhe durante la creazione di istruzioni SQL e dare un'occhiata alle query parametrizzate / alle istruzioni preparate. A proposito di CodeIgniter, dovresti essere interessato anche alla classe Active Record .

Se sei sicuro al 100%, quell'utente deve sempre digitare il numero intero (come nella tua variabile limit ), quindi puoi provare a trasmettere:

$limit = (int)$_GET['limit']

L'uso della trasmissione in questo modo ti protegge da SQL-Injection (perché non c'è modo di inserire un valore non intero nella tua query SQL).

Oh, e non dimenticare che altre variabili potrebbero essere vulnerabili. Quindi assicurati di controllare query , offset e qualsiasi altra variabile, che l'utente controlla. È anche una buona pratica controllare il comportamento dell'applicazione web, quando riceve dati inaspettati - in questo caso potrebbe essere una matrice invece di una stringa: get_stuff?query[]=hello&limit[]=50&offset[]=0

    
risposta data 08.05.2013 - 03:25
fonte
3

Ciò che la maggior parte delle persone non capisce è che le funzioni di escape della stringa SQL sono destinate esclusivamente a valori definiti per valori letterali stringa SQL . Ciò significa che puoi inserire tali valori all'interno di una stringa SQL letterale come '…' o "…" .

Queste funzioni di escape delle stringhe vengono utilizzate per evitare che l'input fornito dall'utente venga interpretato come un valore diverso da un valore di stringa per errore. Questo viene fatto sostituendo le virgolette delimitanti con sequenze di escape speciali in modo che non vengano interpretate come il delimitatore finale ma come una citazione letterale.

Ora se il tuo valore è inteso come un valore intero in SQL come LIMIT richiesto, l'escape del valore con le funzioni di escape della stringa non funziona in quanto ovviamente non è una stringa letterale ma un intero letterale.

Poiché non è una stringa, non vi sono citazioni delimitanti che devono essere ignorate dall'attaccante. E poiché l'iniezione si verifica nella clausola LIMIT , un 50 UNION SELECT … iniettato potrebbe essere possibile sfruttare con successo la vulnerabilità.

Per risolvere questo problema, assicurati che i valori forniti dall'utente siano ciò che ti aspetti. Nel caso di un valore intero, controlla se è effettivamente un valore intero, o in realtà un valore del numero intero del tipo o una rappresentazione stringa valida del valore intero.

Inoltre, esistono librerie che forniscono un'interfaccia semplice alle istruzioni parametrizzate e / o alle istruzioni preparate in cui l'istruzione e i valori dei parametri vengono gestiti separatamente e i valori vengono automaticamente convertiti nel tipo corretto.

Nel tuo caso, dai un'occhiata a Come prevenire l'SQL injection in PHP?

    
risposta data 10.05.2013 - 19:36
fonte
-3

Per valori non interi ho fatto questo, potrebbe non essere il più veloce ma ha funzionato per me ... preg_replace("/[\"'%()@$.!&?_: #\/-]/","", mysql_real_escape_string($_GET['var']));

Anche se non ho mai visto nessuno suggerire di utilizzare preg_replace, non vedo assolutamente alcun modo per aggirarlo per eseguire un attacco di iniezione

    
risposta data 08.05.2013 - 06:18
fonte

Leggi altre domande sui tag