Injection SQL : définition, exemple et protection en PHP
Injection SQL : définition, exemple concret avec OR 1=1 et protection par requêtes préparées en PHP (PDO). Ce qu'un dirigeant doit vérifier sur son site.

Injection SQL : définition simple
L'injection SQL est une faille de sécurité qui permet à un attaquant de modifier les requêtes qu'une application web adresse à sa base de données. Elle naît d'un raccourci : le code insère telle quelle une saisie de l'utilisateur dans une instruction SQL, sans la séparer du reste de la commande. Pour le serveur, il n'y a plus aucune différence entre ce qu'a écrit le développeur et ce qu'a tapé le visiteur.
Vous croiserez souvent l'abréviation anglaise, SQLi. Ce sigle recouvre toute une famille de techniques, qui ont un point commun : du code SQL glissé dans une requête légitime. Depuis des années, la faille figure dans le Top 10 de l'OWASP, la liste de référence des risques web. Je la rencontre encore surtout sur des sites anciens, des extensions mal maintenues et des développements bouclés à la va-vite.
Pourquoi une requête peut être détournée
SQL sert à lire et à modifier des données : afficher un produit, vérifier un mot de passe, enregistrer une commande. Chaque page dynamique construit donc sa requête à partir d'informations fournies par le visiteur. Il suffit d'un guillemet dans ces informations pour fermer la chaîne de texte prévue et ajouter une nouvelle instruction derrière. SQL n'y est pour rien. En cause : la manière dont le code assemble la commande.
Comment fonctionne une attaque d'injection SQL
La logique ne varie presque jamais. L'attaquant commence par repérer un point d'entrée : formulaire de connexion, moteur de recherche interne, paramètre d'URL ou cookie. Il y glisse des caractères qui cassent la syntaxe attendue. Puis il observe. Un message d'erreur SQL, une page blanche ou un résultat inattendu lui confirment qu'il peut aller plus loin.
L'exemple classique de la page de connexion
Prenez un formulaire qui demande un nom d'utilisateur et un mot de passe. Le code PHP colle les deux champs et produit cette requête : select * from users where username = 'saisie1' and password = 'saisie2'. Si une ligne correspond, la personne est connectée. Toute la sécurité repose sur une hypothèse fragile : les deux valeurs doivent rester de simples textes.
Le mécanisme est limpide : le code a fait confiance à une saisie. La partie from users where n'a pas bougé, mais le visiteur en a réécrit la logique. Le même principe s'applique à une URL comme produit.php?id=12, où l'identifiant peut être remplacé par du code.
Les grandes familles d'injection
Les variantes se distinguent surtout par la façon dont l'attaquant récupère le résultat. Voici celles que vous rencontrerez le plus.
- <strong>L'injection classique</strong> : le résultat s'affiche directement dans la page, par exemple grâce à l'opérateur UNION, qui ajoute les lignes d'une autre table.
- <strong>L'injection basée sur les erreurs</strong> : les messages d'erreur du serveur, trop bavards, révèlent la structure de la base.
- <strong>L'injection à l'aveugle</strong> : rien ne s'affiche, mais la page répond différemment selon qu'une condition est vraie ou fausse, ou met plus de temps à charger.
- <strong>L'injection de second ordre</strong> : la donnée piégée est stockée sans problème, puis réutilisée plus tard dans une autre requête vulnérable.
Ce que l'attaquant peut obtenir
Une exploitation réussie peut vider des tables entières : clients, adresses, historiques de commande, hachés de mots de passe. Si le compte SQL a des droits étendus, l'attaquant peut aussi modifier des prix, effacer des données d'application ou se créer un compte administrateur. Pour une PME, les conséquences dépassent la technique. Une fuite de données personnelles peut obliger à prévenir la CNIL et entamer durablement la confiance des clients.
Les erreurs courantes qui ouvrent la porte
D'un audit à l'autre, je retrouve les mêmes vulnérabilités. Elles sont rarement spectaculaires, et c'est justement ce qui les rend dangereuses.
- Concaténer une variable $_GET, $_POST ou $_COOKIE directement dans une chaîne SQL.
- Se reposer sur un contrôle JavaScript côté navigateur, qui se contourne en quelques secondes.
- Échapper les guillemets à la main avec addslashes() plutôt que de paramétrer les requêtes.
- Laisser s'afficher les messages d'erreur SQL en production, ce qui revient à guider l'attaquant.
- Connecter le site avec un compte SQL qui a tous les droits, y compris celui de supprimer la base.
- Garder une version de PHP, un CMS ou une extension qui ne reçoit plus de correctifs.
Toutes ces erreurs mélangent le code et les données. Tant que le texte d'un visiteur peut devenir une commande, votre site reste exposé, et ajouter des filtres par-dessus n'y changera rien.
Se protéger en PHP avec les requêtes préparées
La parade que je recommande sans hésiter s'appelle la requête préparée, ou requête paramétrée. La structure de la requête est envoyée au serveur d'un côté, les valeurs de l'autre. Le serveur compile d'abord la commande avec des emplacements vides, puis il y place les valeurs comme de simples données. Même si une valeur contient des guillemets ou un OR, elle ne sera jamais lue comme une instruction.
Avec PDO
Pour accéder à MySQL, MariaDB ou PostgreSQL en PHP, l'extension recommandée est PDO. Elle permet d'exécuter une requête avec des marqueurs nommés, sans jamais toucher à la chaîne SQL. Un réglage à ne pas oublier : désactivez l'émulation des requêtes préparées, pour que la séparation soit faite par le serveur lui-même.
Avec mysqli
Votre code utilise mysqli ? La logique est la même, avec un point d'interrogation comme marqueur. On écrit $stmt = $mysqli->prepare('SELECT id FROM users WHERE email = ?'), puis $stmt->bind_param('s', $email) et $stmt->execute(). La lettre « s » indique que la valeur est une chaîne. Le choix de la librairie importe peu. L'essentiel est de ne jamais construire la requête par concaténation.
Les protections complémentaires
Les requêtes préparées règlent l'essentiel du problème. Une erreur peut pourtant toujours passer, et les mesures suivantes en limitent les dégâts.
- <strong>Une liste blanche</strong> pour les noms de colonnes ou l'ordre de tri, qui ne peuvent pas être paramétrés.
- <strong>Le moindre privilège</strong> : un compte SQL limité aux opérations utiles, sans droit de supprimer des tables.
- <strong>Des erreurs discrètes</strong> : le détail technique dans les journaux, une page générique pour le visiteur.
- <strong>Des mots de passe hachés</strong> avec bcrypt ou Argon2, pour qu'une fuite reste inexploitable.
- <strong>Un pare-feu applicatif</strong> en filet de sécurité, qui filtre les motifs d'attaque connus.
- <strong>Des mises à jour régulières</strong> de PHP, du CMS et des extensions.
Tester son site : sqlmap, Kali Linux et cadre légal
Pour savoir si un site résiste, les spécialistes utilisent des outils de test automatisés. Le plus connu est sqlmap, un logiciel libre qui essaie de nombreuses variantes d'injection sur un paramètre donné et signale celles qui fonctionnent. Il est installé d'office dans Kali Linux, une distribution conçue pour les tests d'intrusion. Ces outils servent à découvrir les failles avant un attaquant, pas à attaquer.
Attention au cadre légal. Tester un site qui ne vous appartient pas, sans autorisation écrite, est un délit en France, même sans intention de nuire. Le bon cadre est un test d'intrusion commandé par le propriétaire, de préférence sur un environnement de préproduction. Côté code, je fais davantage confiance à une relecture ciblée de toutes les requêtes SQL : on y cherche chaque endroit où une variable entre dans une chaîne de commande.
Voir aussi : les autres failles à surveiller
L'injection SQL n'est pas la seule menace qui pèse sur votre site. La faille XSS suit une logique proche, mais elle injecte du code dans le navigateur plutôt que dans la base. Pour avoir une vue d'ensemble des risques à couvrir, consultez la checklist OWASP Top 10. Un WAF ou pare-feu applicatif ajoute aussi une couche de défense devant le serveur. Si votre site repose sur du code ancien, notre équipe de création de site internet peut auditer vos requêtes et les réécrire proprement.
Questions fréquentes
C'est une attaque qui glisse du code SQL dans un champ de saisie ou une URL pour modifier la requête envoyée à la base de données. Le site exécute alors des commandes imprévues : contourner une connexion, lire des données privées, voire les effacer. Elle n'est possible que si le code mélange les saisies des visiteurs et les instructions SQL.
On insère des caractères spéciaux, par exemple une apostrophe suivie d'une condition toujours vraie, pour changer le sens de la requête. Je vous le dis clairement : ne le faites que sur votre propre site ou dans le cadre d'un test d'intrusion autorisé, avec des outils comme sqlmap. Pour apprendre, il existe des environnements volontairement vulnérables qui vous évitent tout risque juridique.
Utilisez systématiquement des requêtes préparées avec PDO ou mysqli, et ne concaténez jamais une variable dans une chaîne SQL. Ajoutez un compte SQL aux droits limités, des messages d'erreur masqués en production et des mots de passe hachés. Ces mesures sont simples à mettre en place et éliminent la quasi-totalité du risque.


