2010-06-29 23 views
15

Sul PDO::Prepare page si afferma,Le istruzioni preparate in PHP DOP devono essere sottoposte a escape?

"e aiuta a prevenire attacchi di SQL injection, eliminando la necessità di citare manualmente i parametri"

Sapendo questo, c'è una funzione PHP come mysql_real_escape_string() che si prende cura delle punture in fuga per DOP? O il PDO si prende cura di tutto ciò che fugge per me?

EDIT

Mi rendo conto ora che ho chiesto la domanda sbagliata. La mia domanda è stata davvero: "Che cosa si occupa di DOP per me?" Che ora capisco con queste risposte che rimuove davvero solo la necessità di sfuggire alle citazioni. Ma avrei comunque bisogno di fare qualsiasi altra sanitizzazione PHP sui valori che passo alla funzione execute. Come htmlentities(), strip_tags() ... ecc ...

+5

Non esiste una funzione di "sanitizzazione" universale nel mondo. È come la vita reale: lavarsi le mani, usare i preservativi e tenere i soldi nel forziere sicuro sono tutti per la sicurezza. Ma ciò non significa che la tua mela, lavata e avvolta nel preservativo e messa in un forziere sicuro, sia considerata sicura. Ogni funzione di sanitizzazione è per il proprio scopo. Non chiedere sicurezza HTML dalla funzione del database. Sarebbe strano. –

+0

@Col. Shrapnel +1 Bel esempio lol ..... – Metropolis

risposta

24

PDO non sfugge alle variabili. Le variabili e il comando SQL vengono trasferiti in modo indipendente tramite la connessione MySQL. E il tokenizzatore SQL non analizza mai i valori. I valori vengono copiati letteralmente nella memoria del database senza la possibilità di causare alcun danno. Ecco perché non è necessario eseguire il marshalling dei dati con istruzioni preparate.

Si noti che questo è principalmente un vantaggio di velocità. Con mysql_real_escape_string() prima si esegue il marshalling delle variabili in PHP, quindi si invia un comando SQL inefficiente al server, che deve costare di nuovo il costoso comando SQL dai valori. Questo è il motivo per cui si dice spesso che il vantaggio di sicurezza è solo implicito, non il motivo principale per l'utilizzo di PDO.

Se concat il comando SQL e in realtà non usano statments preparati, allora sì, c'è ancora una funzione di via di fuga per i prodotti DOP (non va bene!): $pdo->quote($string)

+0

In realtà questo non è corretto. Sia pdo che adodb usano 'mysql_real_escape_string()' quando si è connessi a mysql. Ho guardato il codice. – rook

+1

@Col. Shrapnel pdo è scritto in C++ e adodb è scritto in php. Entrambi usano mysql_real_escape_string() (che è parte della libreria client mysql ufficiale). Devi sfuggire input ad un certo punto, non c'è altro modo. – rook

+2

@The Rook: Gauging da http://svn.php.net/viewvc/php/php-src/trunk/ext/pdo_mysql/mysql_statement.c?revision=299574&view=markup potrebbe dipendere dal driver di back-end. Il nuovo mysqlnd utilizza sicuramente le statizioni preparate, mentre il precedente potrebbe ricorrere a PDO_ATTR_EMULATE_PREPARES e eseguire l'escape/concatenazione. Dopo tutto, è una delle funzionalità pubblicizzate di PDO per emularlo ** se ** non disponibile. – mario

1

Non devi preoccuparti. PDO non richiede di sfuggire i dati prima di passarli al database.

Edit: Giusto per essere chiari, voglio dire che fino a quando si passa variabili nei vostri parametri (ad esempio, il valore di un campo di modulo), non dovete preoccuparvi di questo. Tuttavia, se stai passando variabili che hai definito come stringhe, ad esempio, ovviamente devi sfuggire a qualsiasi cosa che richieda l'escape in quella stringa per evitare di rompere la sintassi. Tuttavia, questo non avrebbe molto senso dal momento che uno dei principali vantaggi di PDO è il passaggio delle informazioni dall'utente al database senza doverle disinfettare da solo, e non ci sono molte volte (se ce ne sono?) che passeresti stringhe che tu stesso hai definito.

Inoltre, assicurarsi di aver ancora disinfettato i dati per tipo. Ad esempio, assicurarsi che sia un numero intero, se si aspetta che sia, assicurarsi che sia minore o maggiore di x se ci si aspetta che sia, ecc

+0

Ok fico .... quindi tutti i personaggi speciali dovrebbero essere curati? Come tag HTML, citazioni ... ecc. – Metropolis

+0

Supponendo che si vincolino i parametri all'istruzione preparata, sì. (Ovviamente se stai scrivendo il testo tu stesso nel codice PHP, per esempio in una variabile, allora deve essere eseguito l'escape per non interrompere la sintassi.) –

+2

@Metropolis i tag HTML non hanno nulla a che fare con SQL, e le virgolette non sono importanti per il rilegatura, in quanto non vi sono delimitazioni di virgolette circostanti, quindi niente da sfuggire. –

7

Sì e no:

  • letterali che si incorporare nella stringa dell'istruzione è necessario eseguire l'escape come normale.
  • I valori che vengono associati all'istruzione preparata vengono gestiti dalla libreria.
+0

Giusto, questo ha senso – Metropolis

+0

quindi se uso il metodo bindParm non ho bisogno di uscire da qualcosa per evitare un'iniezione, giusto? – Patareco

+1

@Patareco I valori passati a 'PDOStatement :: bindValue()' o 'PDOStatement :: bindParam()' (c'è un'importante differenza!) Dovrebbero essere gestiti correttamente da PDO. Non dovresti scappare da loro, altrimenti verranno salvati nella banca dati sfuggiti. Non ho garanzie, però; ci possono essere bug in PDO/PHP/MySQL che consentono l'iniezione. È inoltre necessario gestire l'output correttamente per evitare l'inserimento di script. –

3

Se si prepara una dichiarazione e si utilizza bindParam o bindValue per fornire variabili, non è necessario sfuggire alle variabili. Nota che queste funzioni presuppongono che la variabile contenga una stringa, quindi usa il terzo parametro per bindValue se vuoi usare booleans o float.

+0

Sto usando preparare ed eseguire ..... Non uso le funzioni bindParam o bindValue. – Metropolis

+1

@Metropolis: Va bene. Se passi il punto interrogativo? oppure: parametri con nome come argomenti per -> execute(), ha lo stesso effetto di bindParam. Basta fare attenzione che questi dovrebbero fare riferimento a colonne di testo quindi. – mario

6

Pochissime persone qui capisce che cosa è e fuga quando usarlo.
L'evasione non rende i dati "sicuri". basta sfuggire ai delimitatori, per distinguere un delimitatore da una parte di dati. field = 'it's me' causerà un errore, mentre field = 'it\'s me' no. Questo è l'unico scopo di fuggire. Quindi, funziona solo quando usi le virgolette. Se non lo fai, scappare diventa inutile.

Utilizzi le virgolette con i segnaposto? No. Quindi, nessuna fuga sarebbe ragionevole.

Quando si utilizza il collegamento, funziona in modo molto diverso.
Non invia l'intera query al server, ma invia la query preparata separatamente dai dati associati. Quindi non può interferire. E quindi nessuna iniezione possibile.

+0

Molto perfetta e giusta risposta. Specialmente l'ultimo paragrafo. –

Problemi correlati