2010-02-06 24 views
6

Ho letto alcune informazioni sulla protezione delle applicazioni PHP e mi sembra che mysqli_real_escape_string sia la funzione corretta da utilizzare quando si inseriscono dati in tabelle MySQL perché addslashes può causare alcuni eventi strani per un aggressore intelligente. Destra?Htmlentities vs addslashes vs mysqli_real_escape_string

Tuttavia, c'è una cosa che mi confonde. Mi sembra di ricordare di essere stato avvisato che addslashes è meglio di htmlentities quando riecheggiamo i dati immessi dall'utente agli utenti per proteggere i loro dati, ma sembra che addslashes sia quello con la vulnerabilità. È vero o mi ricordo male?

risposta

5

Esistono diversi contesti per i dati. Il contesto di inserimento dei dati nel database deve essere sfuggito in modo diverso rispetto al contesto di rendering html/xml o anche di un messaggio di posta elettronica.

L'escaping di dati in un db dovrebbe essere deprecato in tutto il nuovo codice a favore di istruzioni preparate. Chiunque ti dica diversamente ti sta facendo un grande disservizio.

I dati di escape del browser devono essere sfuggiti in un numero di modi diversi a seconda del target. A volte, htmlspecialchars è sufficiente, a volte è necessario utilizzare htmlentities. A volte hai bisogno di entità numeriche. È un argomento su cui si dovrebbe fare qualche ricerca per conoscere tutte le sfumature.

La regola generale in cui vivo è la convalida (non filtro, rifiuto se errata) dell'ingresso & (in base al contesto).

+0

Le istruzioni preparate in velocità sono migliori solo se si utilizza la query preparata più volte in un singolo script. Altrimenti, stai facendo due round trip sul server, una volta per prepararti e una volta per eseguire. Se stai già utilizzando un codice che garantisce automaticamente la convalida dell'input, non so perché le dichiarazioni preparate siano migliori. i documenti mysql trattano questo. http://dev.mysql.com/tech-resources/articles/4.1/prepared-statements.html Se ho torto (è possibile e probabile), per favore dimmi perché. –

+2

Saluti Mike. Ho visto questo argomento contrario troppe volte e penso che debba essere messo a riposo. Per favore, capisci che non sono d'accordo con quello che hai detto. Tuttavia non sono d'accordo con questo consiglio in un forum come questo. Penso che la sicurezza dovrebbe essere una priorità più alta rispetto alle prestazioni soggette a errori in questo caso. L'OP non si lamentava del suo sito, ma piuttosto della mancanza di una chiara definizione tra le diverse tecniche di fuga. Non concorderesti sul fatto che qualcuno che inizia questo viaggio dovrebbe prendere la strada più sicura? –

+0

Sono assolutamente d'accordo. Stavo chiedendo delle prestazioni per me stesso perché non sono sicuro della risposta. Non l'ho detto chiaramente. –

0

È inoltre possibile utilizzare PDO libs che esegue la maggior parte delle operazioni di escape per l'utente, nel caso in cui si possa utilizzare PHP5 sui server.

Sul eco indietro io personalmente preferisco htmlspecialchars, ma mi potrebbe correggere

11

Si tratta di strumenti diversi per scopi diversi.

mysqli_real_escape_string rende i dati sicuri per l'inserimento in MySQL (ma le query parametrizzate sono migliori).

htmlentities rende dati al sicuro per l'output in un documento HTML

addslashes rende sicuro per un paio di altre situazioni di dati, ma non è sufficiente per MySQL

+0

Dovresti pubblicare un caso in cui addslashes() fallisce e mysql_real_escape_string() lo interrompe. Non penso che tu possa, ma qui c'è una query in cui entrambi falliscono: mysql_query ("seleziona * dall'utente dove id =". $ _ OTTIENI [id]); – rook

+0

addslashes presuppone che tutto sia a 8 bit. mysql_real_escape_string prende in considerazione la codifica dei caratteri quando esegue la sua codifica. Prova: http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string –

+0

@Eric, che è stato corretto. Prova il suo exploit su un sistema completamente aggiornato, fallirà. – rook

0

sì, utilizzare il mysqli_real_escape_string o una libreria come DOP su tutti gli utenti ingresso. Quando eseguo il richiamo, utilizzo htmlentities con ENT_QUOTES come secondo parametro, poiché esegue il escape di tutti i caratteri applicabili alle loro entità html, comprese le virgolette.

0

Nota: Utilizzare htmlentities() in un documento con codifica UTF-8 dovrebbe essere evitato.Vedere:

Prestare attenzione alla (citato da phpwact.org):

con i browser web moderni e molto estesa supporto per UTF-8, si don' t bisogno di htmlentities perché tutti questi caratteri possono essere rappresentati direttamente in UTF-8. Ancora più importante, nel generale, solo i browser supportano i caratteri speciali HTML - un normale editor di testo , ad esempio, non è a conoscenza delle entità HTML . A seconda di cosa stai facendo , con htmlentities è possibile che riduca la capacità degli altri sistemi di "consumare" i tuoi contenuti in .

anche (non confermato, ma sembra ragionevole - da anon commento qui), entità carattere (roba del genere »o -) non funzionano quando un documento viene servita come application/xml + xhtml (a meno che non definire loro). Puoi comunque scappare con il modulo numerico.

+1

L'uso comune di 'htmlentities()' non sta rendendo i caratteri "strani" ma piuttosto evita che testo potenzialmente pericoloso sia analizzato come markup, e questo non ha nulla a che fare con la codifica. –

+0

È possibile evitare il testo potenzialmente pericoloso con htmlspecialchars(). htmlentities() ha il sovraccarico di convertire caratteri "sicuri" e presenta problemi aggiuntivi che ho menzionato prima. – Dor

0

Un'altra soluzione interessante per PHP 5.2 e sopra è di utilizzare l'estensione del filtro: http://www.php.net/manual/en/book.filter.php

Esso consente di analizzare e disinfettare input dell'utente. Sono disponibili molti filtri incorporati e possono essere combinati con flag per modificare il loro comportamento. Inoltre, questi filtri possono anche essere utilizzati per convalidare/disinfettare int, float, e-mail, espressioni regolari specifiche.

Personalmente ho iniziato a usarli nei miei progetti per convalidare i moduli e generare dati immessi dall'utente, e sono molto contento di averlo fatto. Sebbene, quando inserisco i valori in un database MySQL, utilizzo query preparate per una maggiore sicurezza. Queste soluzioni insieme possono aiutare a evitare la maggior parte delle iniezioni SQL e degli attacchi di tipo XSS.

0

Non è possibile avere una funzione di "fuga" e aspettarsi che funzioni sempre. Ci sono diversi attacchi che richiedono routine di igiene specifiche. L'unico modo per comprendere questo concetto è scrivere un codice vulnerabile e quindi sfruttarlo. Scrivere codice di exploit è di vitale importanza per la comprensione di qualsiasi sistema di sicurezza.

Per esempio questa query è vulnerabile a SQL Injection:

$host=htmlspecialchars($_GET[host],ENT_QUOTES); 
$name=htmlspecialchars($_GET[name],ENT_QUOTES); 
mysql_query("select * from user where Host='$host' and Name='$name' "); 

Exploit: http://localhost/sqli_test.php?host= \ & name =% 20sleep (20) -% 201

La migliore funzione di fuga per mysql è mysqli_real_escape_string() ma questo può fallire:

mysql_query("select * from user where id=".mysqli_real_escape_string($_GET[id])); 

exploit: http://localhost/sqli_test.php?id=1%20or%20sleep(20)

In effetti, il modo migliore per prendersi cura di SQL injection non è chiamare una funzione di escape, poiché utilizza i parametri parametrizzati di ADODB per l'iniezione sql. Utilizza htmlspecialcahrs ($ var, ENT_QUTOES) per XSS.Leggi lo OWASP top 10 perché c'è molto di più di quello che può andare storto con la sicurezza delle applicazioni web.

Problemi correlati