Rappel théorique
Une injection se produit lorsque des données fournies par un utilisateur sont insérées dans une commande ou une requête interprétée par un moteur (SQL, système de fichiers, LDAP...) sans validation ni séparation entre le code et la donnée. L'injection SQL est la forme la plus courante : un attaquant modifie la requête SQL exécutée par l'application pour lire, modifier ou supprimer des données auxquelles il ne devrait pas avoir accès.
Conséquences typiques : accès non autorisé à la base de données, contournement de l'authentification, exfiltration de données sensibles (mots de passe, données personnelles), voire modification/suppression de données.
Exemple de code non sécurisé
$q = $_GET['q'];
$sql = "SELECT id, nom, description, prix, categorie FROM produits WHERE nom LIKE '%$q%'";
$resultats = $pdo->query($sql); // la valeur de $q fait partie intégrante de la requête
Si $q contient lui-même du SQL (par exemple ' UNION SELECT ... --),
ce SQL est exécuté tel quel par la base de données.
Démo vulnérable
Un moteur de recherche de produits qui construit sa requête SQL par concaténation directe de l'entrée utilisateur.
Démo sécurisée
La même fonctionnalité, mais la requête est préparée avec des paramètres liés (prepared statements) : l'entrée utilisateur est toujours traitée comme une donnée, jamais comme du code SQL.
Pour aller plus loin
- Toujours utiliser des requêtes préparées (PDO, mysqli avec paramètres liés) plutôt que la concaténation de chaînes.
- Appliquer le principe du moindre privilège : le compte de connexion à la base de données ne doit avoir que les droits strictement nécessaires.
- Valider/filtrer les entrées côté serveur, même si des requêtes préparées sont utilisées (défense en profondeur).
- Le même principe s'applique à toute autre injection : commandes système (
exec,system), LDAP, NoSQL, etc.