Comment prévenir l’injection SQL en PHP ?

Pour éviter les attaques par injection SQL, il est essentiel de séparer les données du langage SQL afin de les traiter correctement. Cela garantit que les données restent des données et ne soient jamais interprétées comme des commandes par l’analyseur SQL, quelle que soit la base de données utilisée.

Bien que vous puissiez créer une instruction SQL avec des parties de données correctement formatées, il est conseillé d’utiliser des instructions préparées et des requêtes paramétrées si vous ne maîtrisez pas bien les détails. Ces instructions SQL sont envoyées au serveur de la base de données et analysées sans aucun paramètre. Ainsi, il est impossible pour un attaquant d’injecter du code SQL malveillant. Opter pour cette méthode est donc un moyen efficace de prévenir les attaques par injection SQL.

Pour ce faire, deux options s’offrent à vous :

1. Utiliser PDO (pour tout pilote de base de données pris en charge) :


$stmt = $pdo->prepare('SELECT * FROM salaries WHERE nom = :nom') ;
$stmt->execute([ 'nom' => $nom ]) ;

foreach ($stmt as $row) {
    // Fait quelque chose avec $row
}

2. Utilisation de MySQLi (pour MySQL) :

Depuis PHP 8.2+, nous pouvons utiliser execute_query() qui prépare, lie les paramètres et exécute la requête SQL en une seule méthode :

$result = $dbConnection->execute_query('SELECT * FROM employees WHERE name = ?', [$name]) ;
while ($row = $result->fetch_assoc()) {
// Fait quelque chose avec $row
}

Jusqu’à PHP8.1 :

$stmt = $dbConnection->prepare('SELECT * FROM employees WHERE name = ?') ;
$stmt->bind_param('s', $name) ; // 's' spécifie le type de la variable => 'string'
$stmt->execute() ;
$result = $stmt->get_result() ;
while ($row = $result->fetch_assoc()) {
// Faire quelque chose avec $row
}

Explication

L’utilisation d’instructions préparées est une méthode sûre pour prévenir les attaques par injection SQL. Lorsque vous envoyez une déclaration SQL à la fonction prepare, celle-ci est analysée et compilée par le serveur de base de données. En spécifiant des paramètres sous forme de ?, ou d’un paramètre nommé comme :name, vous indiquez au moteur de base de données les éléments à filtrer. Lorsque vous appelez execute, l’instruction préparée est combinée avec les valeurs des paramètres que vous avez spécifiées.

Il est important de noter que les valeurs des paramètres sont combinées avec l’instruction compilée et non avec une chaîne SQL. Cela limite le risque d’injection SQL en empêchant l’ajout de chaînes malveillantes dans le code SQL envoyé à la base de données. Tous les paramètres envoyés seront traités comme des chaînes de caractères, mais le moteur de la base de données peut également optimiser leur format pour une exécution plus rapide.

Ainsi, en utilisant des instructions préparées, si votre variable $name contient « Jeanne’ ; DELETE FROM employees », elle sera traitée comme une chaîne de caractères et ne supprimera pas la table. De plus, en exécutant plusieurs fois la même instruction, celle-ci sera analysée et compilée une seule fois, ce qui accélère le processus.

En conclusion, l’utilisation d’instructions préparées est une méthode recommandée pour garantir la sécurité de vos requêtes SQL et prévenir les attaques par injection SQL.

Un exemple (en utilisant PDO) :

$preparedStatement = $db->prepare('INSERT INTO table (column) VALUES (:column)') ;
$preparedStatement->execute([ 'column' => $unsafeValue ]) ;

Vous souhaitez faire appel à un développeur web ?

Les derniers articles de nos développeurs web