Mysql
 sql >> Database >  >> RDS >> Mysql

Sostituzione delle funzioni mysql_* con PDO e istruzioni preparate

Grazie per la domanda interessante. Ecco a te:

Sfugge a personaggi pericolosi,

Il tuo concetto è completamente sbagliato.
In effetti i "personaggi pericolosi" sono un mito, non ce ne sono. E mysql_real_escape_string escaping ma semplicemente un delimitatore di stringa . Da questa definizione puoi concludere i suoi limiti:funziona solo per stringhe .

tuttavia, è ancora vulnerabile ad altri attacchi che possono contenere caratteri sicuri ma possono essere dannosi per la visualizzazione dei dati o, in alcuni casi, per la modifica o l'eliminazione dannosa di dati.

Stai mescolando tutto qui.
Parlando di database,

  • per le stringhe NON vulnerabile. Finché le tue stringhe vengono citate ed evitate, non possono "modificare o eliminare i dati in modo dannoso".*
  • per gli altri dati typedata - sì, è inutile . Ma non perché sia ​​in qualche modo "non sicuro", ma solo per un uso improprio.

Per quanto riguarda la visualizzazione dei dati, suppongo che sia fuori tema nella domanda relativa al PDO, poiché PDO non ha nulla a che fare nemmeno con la visualizzazione dei dati.

evasione dell'input dell'utente

^^^ Un'altra illusione da notare!

  • l'input di un utente non ha assolutamente nulla a che fare con l'escape . Come puoi imparare dalla definizione precedente, devi evitare le stringhe, non qualsiasi "input dell'utente". Quindi, ancora:

    • hai stringhe di escape, indipendentemente dalla loro origine
    • è inutile sfuggire ad altri tipi di dati, indipendentemente dalla fonte.

Hai capito?
Ora, spero che tu capisca i limiti della fuga e l'idea sbagliata dei "personaggi pericolosi".

Da quanto ho capito, l'uso di PDO/dichiarazioni preparate è molto più sicuro

Non proprio.
In effetti, ce ne sono quattro diverse parti della query che possiamo aggiungere dinamicamente:

  • una stringa
  • un numero
  • un identificatore
  • una parola chiave sintattica.

quindi, puoi vedere che l'escape copre solo un problema. (ma ovviamente, se tratti i numeri come stringhe (mettendoli tra virgolette), quando applicabile , puoi anche metterli al sicuro)

mentre le dichiarazioni preparate coprono - ugh - intere 2 questioni! Un grosso problema;-)

Per gli altri 2 problemi, vedere la mia risposta precedente, In PHP quando invio stringhe al database dovrei occuparmi dei caratteri illegali usando htmlspecialchars() o usare un'espressione regolare?

Ora, i nomi delle funzioni sono diversi, quindi mysql_query, mysql_fetch_array, mysql_num_rows ecc. non funzioneranno più.

Questa è un'altra, grave illusione degli utenti di PHP , un disastro naturale, una catastrofe:

Anche quando si utilizza il vecchio driver mysql, non si dovrebbero mai usare funzioni API nude nel loro codice! Bisogna inserirli in qualche funzione di libreria per l'uso quotidiano! (Non come un rito magico ma solo per rendere il codice più breve, meno ripetitivo, a prova di errore, più coerente e leggibile).

Lo stesso vale anche per la DOP!

Ora di nuovo con la tua domanda.

ma usandoli questo elimina la necessità di usare qualcosa come mysql_real_escape_string?

SI.

Ma penso che questa sia più o meno l'idea di cosa dovrebbe essere fatto per recuperare un utente da un database

Non per recuperare, ma per aggiungere qualsiasi dato alla query !

devi dare una lunghezza dopo PDO:PARAM_STR se non sbaglio

Puoi, ma non devi.

Ora, è tutto sicuro?

In termini di sicurezza del database non ci sono punti deboli in questo codice. Niente da mettere al sicuro qui.

per la sicurezza della visualizzazione, cerca in questo sito il XSS parola chiave.

Spero di aver fatto luce sulla questione.

A proposito, per i lunghi inserti puoi usare la funzione che ho scritto un giorno, Inserisci/aggiorna la funzione di supporto utilizzando PDO

Tuttavia, al momento non sto utilizzando istruzioni preparate, poiché preferisco i miei segnaposto fatti in casa su di loro, utilizzando una libreria Ho menzionato sopra. Quindi, per contrastare il codice pubblicato dal riha di seguito, sarebbe breve come queste 2 righe:

$sql  = 'SELECT * FROM `users` WHERE `name`=?s AND `type`=?s AND `active`=?i';
$data = $db->getRow($sql,$_GET['name'],'admin',1);

Ma ovviamente puoi avere lo stesso codice anche usando istruzioni preparate.

* (yes I am aware of the Schiflett's scaring tales)