L'insertion directe d'une entrée utilisateur dans une requête SQL sans aucune modification laisse une application vulnérable aux attaques par injection SQL. Pour éviter cela, il est crucial de séparer les données de SQL pour garantir que les données restent en tant que données et ne sont jamais interprétées comme des commandes par l'analyseur SQL.
La solution la plus efficace
L'approche recommandée pour éviter les attaques par injection SQL, quelle que soit la base de données utilisée, consiste à utiliser des instructions préparées et paramétrées requêtes. Il s'agit d'instructions SQL analysées indépendamment par le serveur de base de données avec les paramètres. Cette approche empêche les attaquants d'injecter du SQL malveillant.
Implémentation à l'aide de PDO ou MySQLi
PDO fournit une solution universelle pour tous les pilotes de base de données pris en charge, tandis que MySQLi est spécifique vers MySQL.
$stmt = $pdo->prepare('SELECT * FROM employees WHERE name = :name'); $stmt->execute(['name' => $name]); foreach ($stmt as $row) { // Do something with $row }
$result = $db->execute_query('SELECT * FROM employees WHERE name = ?', [$name]); while ($row = $result->fetch_assoc()) { // Do something with $row }
$stmt = $db->prepare('SELECT * FROM employees WHERE name = ?'); $stmt->bind_param('s', $name); // 's' specifies string type $stmt->execute(); $result = $stmt->get_result(); while ($row = $result->fetch_assoc()) { // Do something with $row }
Configuration correcte de la connexion
Lors de l'utilisation de PDO pour MySQL, assurez-vous que les véritables instructions préparées sont utilisées en désactivant émulation.
$dbConnection = new PDO('mysql:dbname=dbtest;host=127.0.0.1;charset=utf8mb4', 'user', 'password'); $dbConnection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); $dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Pour MySQLi, utilisez ce qui suit :
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); // error reporting $dbConnection = new mysqli('127.0.0.1', 'username', 'password', 'test'); $dbConnection->set_charset('utf8mb4'); // charset
Explication
Les instructions préparées sont analysées et compilées par le serveur de base de données , séparant l'instruction SQL des paramètres. Lorsque les paramètres sont transmis, ils sont combinés avec l'instruction compilée sous forme de chaînes, éliminant ainsi le risque d'injection SQL.
Requêtes dynamiques
Bien que les instructions préparées puissent être utilisées pour paramètres dans les requêtes dynamiques, la structure de la requête dynamique elle-même ne peut pas être paramétrée. Dans ces cas, il est conseillé d'utiliser un filtre de liste blanche.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!