Come prevenire le SQL injection in PHP

di Lorenzo Neri

In questo articolo vediamo un processo che richiede diversi ragionamenti e soluzioni: come prevenire le SQL injection in PHP.

Ciao mi chiamo Lorenzo Neri e sono un informatico: realizzo contenuti per aiutare le persone a padroneggiare l’arte del nuovo millennio, ovvero l’informatica!

In diverse situazioni può capitare che un utente possa agire sul nostro database in modo tale da comprometterne la sicurezza, per esempio tramite i dati provenienti da un form e le variabili inviate tramite HTTP.

Facciamo un esempio concreto:

$variabile= $_POST['email'];
mysql_query("SELECT * FROM users where email='$variabile'");

E il valore della variabile può contenere qualcosa come:

miaemail@sito.it DROP TABLE table;--

E la query eseguita sarebbe:

SELECT * FROM users where email='miaemail@sito.it DROP TABLE table;--

In altre parole una bella SQL injection come si deve!

Perciò, come prevenire un disastro simile nei nostri file PHP?

Usare query parametriche

Usare query parametriche è molto efficace per prevenire le SQL injection. Questo, perché il SQL vero e proprio viene inoltrato al server in modo separato rispetto ai parametri.

In questo modo, diventa pressoché impossibile eseguire una SQL injection.

Per farlo, abbiamo due strade differenti.

Usare PDO

PDO è il primo modo che vediamo per scrivere query parametriche e considera che funziona per qualsiasi database:

$query = $pdo->prepare('SELECT * FROM users WHERE email = :email');
query->execute([ 'email' => $email ]);
foreach ($query as $row) {
   //Operazioni da eseguire
}

Usare MySQLi

Questo ovviamente funziona solo per i database MySQL. MySQLi è un altro modo per eseguire query parametriche:

$query = $dbConnection->prepare('SELECT * FROM users WHERE email = ?');
$query->bind_param('s', $email); // 's' specifica che la variabile in questione è una stringa
$query->execute();
$result = $query->get_result();
while ($row = $result->fetch_assoc()) {
   //Operazioni da eseguire
}

Abbiamo visto il primo punto atto a prevenire le SQL injection. Andiamo oltre!

Impostare correttamente la connessione al DataBase

C’è da fare una specifica se vuoi usare PDO per accedere a un database MySQL. Le parametrizzazioni non sono impostate di default.

Per risolvere questo problema, bisogna eseguire quanto segue:

$dbConnection = new PDO('mysql:dbname=dbinformatico;host=127.0.0.1;charset=utf8', 'user', 'password');
$dbConnection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

In questo modo ti eviterai non pochi problemi legati ad eventuali “Fatal Error” generati da una configurazione errata di PDO.

Non abbiamo finito qui ovviamente, vediamo un altro modo per prevenire le SQL injection sempre in PHP.

Query parametrizzate dinamicamente

Certo, tutto molto bello, ma come facciamo a rendere dinamiche le query parametrizzate?

In alcuni casi purtroppo viene difficile gestirle, specialmente per alcuni parametri che no possono essere parametrizzati.

Quello che possiamo fare però, è creare una whitelist. Una lista di termini che permettiamo di essere usati nelle query, tuttavia dobbiamo parametrizzarli noi.

Per esempio:

if (empty($ordinamento) || $ordinamento !== 'DESC){
  $ordinamento = 'ASC';
}

L’esempio che abbiamo visto sopra permette a quella variabile di avere come valore solo ed esclusivamente “ASC” oppure “DESC”, in modo tale da garantire al 100% nelle query parametriche un minimo di dinamicità e sicurezza.

Continua a scoprire di più con questi articoli!

Lascia un commento

Questo sito potrebbe fare uso di cookie e siccome l'UE mi obbliga a fartelo presente, eccoti il classico banner dove puoi decidere come gestirli. Accetta Leggi di più