La select tradizionale espone a potenziali rischi dal punto di vista dell’iniezione di codice malevolo, le sql injection infatti sono ancora al primo posto sia per la facilità di sfruttamento della vulnerabilità, sia per i rischi ad essa connessi.
Il rischio è legato all’uso incauto della variabile:
e, usata senza controllo, potrebbe contenere qualsiasi codice malevolo .
La soluzione risiede nell’uso dei prepared statement che ci garantiscono un miglioramento della sicurezza e anche delle buone performance di esecuzione, in particolare nel caso di operazioni ripetute.
Il primo passo per utilizzare i prepared statement sarà quello di preparare la nostra query sostituendo le due variabili con dei segnaposto (placeholder) che verranno valorizzati in fase di binding:
La separazione fra la preparazione dell’SQL e i dati ci permette di avere una protezione rispetto alle SQL injection, infatti i dati provenienti dall’utente verranno gestiti al di fuori dell’istruzione SQL.
A livello di sintassi si deve registrare l’assenza dei delimitatori attorno al parametro: in questo caso pur trattandosi di stringhe non è necessario delimitarle, infatti l’associazione con il tipo di dato verrà fatta in fase di binding.
I valori di bind sono i seguenti:
Valore | Descrizione |
---|---|
“s” | Corrisponde a variabili associate al tipo di dato stringa. |
“i” | Corrisponde a variabili associate al tipo di dato numeri interi. |
“d” | Corrisponde a variabili associate al tipo di dato numeri double. |
“b” | Corrisponde a variabili associate al tipo di dato BLOB, formato binario. |
la variabile result mi ritorna il valore 0 o 1 de il risultato del bind è corretto.
Tale operazione permette una velocizzazione dell’accesso al database e una maggiore sicurezza dei campi che verranno inseriti o cancellati.
“By using prepared statements you are separating SQL queries from user entered data. Instead of input data, you put placeholders (‘?’ char) in your SQL query. Then you send the query to the DBMS server (e.g.: MySQL) by means of the “mysqli::prepare” method. So the server checks that everything is ok and, if so, it waits for input data. By now it already knows your query. Just it has to wait for input data to bind to the query. “
Al termine del fie php inserisco sempre:
Quindi il codice sorgente che avevo usato precedentemente con il prepare, bind ed execute adesso DEVE esesere scritto nella seguente maniera:
DEVE essere presente il metodo store_result() per poi usare il metodo num_rows, alla fine del bind usare sempre il metodo close().
Ricapitolando
prepare
bind
variabili
store_result —>solo per select
metodi sulla select
close()