2009-04-09 8 views
25

C'è un commento in un'altra domanda che dice quanto segue:..Perché utilizzare una dichiarazione preparata su mysql è più sicura rispetto all'utilizzo delle funzioni di escape comuni?

"Quando si tratta di query di database, cercare sempre e l'uso preparato query parametrizzate Il mysqli e librerie PDO supportano questa Questa è infinitamente più sicuro che usare le funzioni di escape come mysql_real_escape_string. "

Source

Quindi, quello che voglio porre è: query con parametri perché sono preparati più sicuro?

risposta

42

Un punto importante che penso che le persone qui siano mancanti è che con un database che supporta le query con parametri, non c'è "fuga" di cui preoccuparsi. Il motore di database non combina le variabili associate nell'istruzione SQL e quindi analizza l'intera cosa; Le variabili associate vengono mantenute separate e mai analizzate come un'istruzione SQL generica.

Ecco da dove provengono la sicurezza e la velocità. Il motore di database sa che il segnaposto contiene solo dati, quindi non viene mai analizzato come un'istruzione SQL completa.L'accelerazione arriva quando prepari una dichiarazione una volta e poi la esegui molte volte; l'esempio canonico sta inserendo più record nella stessa tabella. In questo caso, il motore del database deve analizzare, ottimizzare, ecc. Solo una volta.

Ora, un getcha è con le librerie di astrazione del database. A volte lo falsificano semplicemente inserendo le variabili associate nell'istruzione SQL con la corretta escaping. Comunque, è meglio che farlo da solo.

+0

Grazie per aver spiegato :) –

+0

Quindi è più veloce ma la sicurezza è la stessa? Voglio dire che non puoi essere più sicuro che completamente al sicuro. Vorrei anche qualche prova delle teorie della velocità. –

7

Per uno, stai lasciando la fuga di personaggi pericolosi nel database, che è molto più sicuro di te, l'umano.

... non dimenticherà di uscire o di perdere caratteri speciali che potrebbero essere utilizzati per iniettare un codice SQL malevolo. Per non parlare, si potrebbe ottenere un miglioramento delle prestazioni per l'avvio!

+0

Ma come funziona il database conoscono la differenza tra ciò che è pericoloso e tra quello che voglio veramente fare? –

+0

Beh, sa quali caratteri sono malvagi, quindi dovrebbe anteporre il carattere di escape '\' in MySQL prima del personaggio malvagio. Questo continua a essere la domanda così com'è, ma non onorerà nessuno dei caratteri speciali che appaiono in un'associazione. – alex

+0

Inoltre, si specificano le 'associazioni' separatamente (non concatenate nella query) e si inserisce semplicemente un segnaposto nella query dove dovrebbero apparire. Il database (penso, forse PDO lo fa?) Poi sfugge ai caratteri all'interno dei binding. – alex

0

Il caso migliore, potrebbe non essere, ma è almeno altrettanto sicuro; e perché cogliere l'occasione?

5

io non sono estremamente addentro in sicurezza, ma qui è una spiegazione che spero vi aiuterà a:

Diciamo di avere una dichiarazione come:

selezionare [intero] da miodb

Pretend quando lo prepari, l'istruzione è compilata in byte nella nostra implementazione dell'immio sql.

  01     00 00     23 
Opcode for select   Prepared bytes  number of "mydb" 
          for your integer 

Ora quando si esegue, si inserisce il numero nello spazio riservato per l'istruzione preparata.

Confrontalo con se usi solo la fuga, potresti inserire un numero di parole incomprensibili e magari causare un sovraccarico della memoria, o qualche comando binario di sql che hanno dimenticato di scappare.

+0

Questo è un buon esempio, grazie. –

2

Perché con le istruzioni preparate, non è possibile dimenticare di sfuggire al contenuto. Quindi non c'è modo di introdurre l'insicurezza.

mysql_real_escape_string è sicuro come istruzioni preparate SE ricordi di usare mysql_real_escape_string ogni volta che chiami mysql_query, ma è facile da dimenticare.

1

La funzione non è sicura a causa di questo exploit http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string. Questo è il motivo per cui sono preferite le dichiarazioni preparate e anche il miglioramento delle prestazioni.

+0

Credo che leggo correttamente quel blog collegato che ha problemi con addslashes che sono insicuri, non mysql_real_escape_string. Alla fine dice che quest'ultima è un'opzione valida, se la gente si ricorda di farlo, ma la gente tende a dimenticare di chiamarla. L'utilizzo di istruzioni preparate aiuta a risolvere questo problema di memoria. –

+0

Anche questo è un link interessante, che punta a un potenziale problema con mysql_real_escape_string, sebbene oscuro: http://ilia.ws/archives/103-mysql_real_escape_string-versus-Prepared-Statements.html –

1

Le dichiarazioni preparate risolvono un fundamental problem of application security che la semplice sanificazione dei dati non ha: Si ottiene una separazione completa dei dati e le istruzioni. Quando i due si confondono, l'insicurezza è il risultato. Questo vale sia per l'iniezione SQL che per i buffer overflow.

(Ci sono altri modi per essere insicura.)

Problemi correlati