mysql_escape_string ha vulnerabilità di sicurezza se tutte le tabelle utilizzano la codifica Latin1?

6

Ho sentito che la funzione PHP mysql_escape_string presenta vulnerabilità di sicurezza legate a caratteri byte. Ci sono vulnerabilità se tutte le tabelle utilizzano la codifica Latin1?

    
posta user5385 11.10.2011 - 05:24
fonte

3 risposte

6

Il problema è che mysql_escape_string() non controlla il database per la codifica dei caratteri. Di conseguenza, mysql_escape_string() non è a conoscenza della codifica del database e può trattare i caratteri multi-byte come caratteri a byte singolo. Ciò potrebbe comportare l'escape degli ultimi due byte in un carattere riservato come e innumerevoli altri caratteri che hanno rilevanza speciale per il motore SQL.

In tal caso, l'utente malintenzionato potrebbe aggiungere comandi SQL aggiuntivi per ottenere l'accesso a dati o funzioni non previsti. Questo è il motivo per cui la funzione è deprecata e l'uso di mysql_real_escape_string() è raccomandato.

mysql_real_escape_string() funziona in modo quasi identico tranne che si connette al database per determinare quale codifica viene utilizzata dal database, evitando problemi noti di escape multi-byte.

Nota inoltre che mysql_escape_string() e mysql_real_escape_string() non sfuggono ai caratteri% e _ (come per il riferimento manuale link e link vedi note). Ciò potrebbe consentire l'accesso a dati che non sono intesi quando vengono utilizzati con parole chiave come LIKE , quindi è necessario prestare particolare attenzione.

Aggiorna

So, what encoding does mysql_escape_string assume?

Credo che sia ASCII, tuttavia non sono in grado di confermarlo. Indipendentemente da ciò non fa alcuna differenza per il risultato che è; l'utilizzo di Latin1 per la codifica del database potrebbe comportare una vulnerabilità di sicurezza se non correttamente codificato.

Si noti inoltre che questa non è solo vulnerabilità con il database. All'interno dello script application / server-side è necessario prestare attenzione quando si gestisce l'input per essere consapevoli di come vengono passate le stringhe dalla funzione alla funzione e assicurarsi che la codifica corretta sia preservata. Idealmente usare UTF-8 end-to-end sarebbe buono ma non sempre un'opzione.

    
risposta data 11.10.2011 - 06:52
fonte
6

Personalmente, penso che tu stia facendo la domanda sbagliata. Se si desidera evitare le vulnerabilità di SQL injection - come si dovrebbe - la risposta non è di usare mysql_escape_string più attentamente. La risposta corretta è usare le istruzioni preparate.

Il problema fondamentale è che mysql_escape_string è fragile, ed è difficile prevedere tutti i modi specifici in cui potrebbe rompersi. Hai appreso una fonte di fragilità in mysql_escape_string , e ora ti chiedi se sia l'unica fonte.

Personalmente, prendo una lezione diversa. La lezione che traggo è che, se la sicurezza è il lavoro, mysql_escape_string è lo strumento sbagliato per il lavoro. Invece, dovresti usare istruzioni preparate (query parametrizzate).

Nel mondo della sicurezza, è ampiamente accettato che il modo più efficace per evitare l'iniezione SQL è usare istruzioni preparate. Non provare a scappare / codificare i dati e quindi creare una query SQL utilizzando la concatenazione di stringhe; tale approccio è fragile e può facilmente interrompersi se, ad esempio, il database interpreta la query in modo diverso da quanto previsto. Quindi il mio consiglio è: non cercare di diventare furbo, usa solo dichiarazioni preparate e sii felice.

    
risposta data 11.10.2011 - 08:20
fonte
1

Alla risposta di BernieWhite , mysql_escape_string() esegue l'escape in completa ignoranza della codifica della stringa effettivamente utilizzata < em> per la connessione al database (che è separato da quello utilizzato nelle tabelle).

Pertanto, tenta di sfuggire ' caratteri sostituendoli con \' ogni volta che si verificano. Lo fa su una base bytewise, sostituendo ogni occorrenza di 0x27 con 0x5c27 (cioè funziona efficacemente supponendo che la stringa sia codificata in un superset a singolo byte di ASCII); per esempio, convertirà la stringa 0xbf27 in 0xbf5c27 -ma se la codifica della connessione è GBK, questo avrà convertito una stringa non valida in 縗' (nota il carattere% non defunti% co_de).

Quindi è stato introdotto ' per eseguire correttamente l'escaping, cioè in base alla codifica dei caratteri di connessione. Tuttavia, si deve quindi informare la libreria client della codifica dei caratteri chiamando mysql_real_escape_string()

Ma anche se si usa mysql_set_charset() , ci sono ancora altri casi limite che possono lasciarti vulnerabile. Come spiegato in la mia risposta a "SQL injection che aggira mysql_real_escape_string ()" su StackOverflow:

TL;DR

mysql_real_escape_string() will provide no protection whatsoever (and could furthermore munge your data) if:

  • MySQL's NO_BACKSLASH_ESCAPES SQL mode is enabled (which it might be, unless you explicitly select another SQL mode); and

  • your SQL string literals are quoted using double-quote " characters.

A causa di queste difficoltà pratiche nel garantire che i letterali stringa incorporati siano gestiti in modo sicuro, in genere si consiglia di non tentare nemmeno! Invece, si possono inviare valori letterali alla connessione al database in pacchetti completamente separati da SQL; di conseguenza, il server non tenterà nemmeno tentativo di analizzare questi valori per qualcos'altro: questo è noto come "parametrizzazione della query", è ciò che la risposta di DW suggerisce ed è ben spiegata in Come posso evitare l'SQL injection in PHP ?

    
risposta data 25.04.2014 - 17:03
fonte

Leggi altre domande sui tag