Une revue de code montre une requête SQL construite en concaténant une saisie utilisateur. Quelle est la bonne correction ?
Réponse courte
Les requêtes paramétrées sont la vraie correction : elles séparent le code des données, de sorte que la saisie utilisateur est toujours traitée comme une valeur, jamais comme du SQL pouvant modifier la structure de la requête. L'échappement manuel est source d'erreurs et contournable selon les encodages et les dialectes. Un WAF est un contrôle compensatoire, pas un correctif, et les astuces d'encodage le déjouent. Une vérification de longueur n'empêche en rien l'injection. Corrigez au niveau de la requête.
Une requête assemblée par concaténation de chaînes laisse un texte contrôlé par l'attaquant devenir une partie du SQL que la base de données analyse. La cause profonde est que le code et les données sont mélangés dans la même chaîne. Toute correction qui ne les sépare pas ne traite que les symptômes.
Pourquoi les requêtes paramétrées sont la solution
Avec une instruction préparée, le texte SQL avec ses paramètres fictifs est envoyé d'abord à la base et compilé ; les valeurs utilisateur sont envoyées séparément et liées à ces paramètres. L'analyseur a déjà déterminé la structure de la requête avant même de voir la saisie, donc une valeur comme ' OR 1=1-- ne peut être qu'une chaîne littérale — jamais une nouvelle syntaxe SQL. C'est structurel, et non un filtre à ajuster en permanence, d'où la recommandation canonique de l'OWASP.
Pourquoi les autres options échouent
- Échapper les guillemets avec une expression régulière tente de neutraliser à la main les caractères dangereux. Cela casse avec les encodages alternatifs, l'Unicode, les contextes numériques sans guillemets et les subtiles différences d'échappement entre MySQL, PostgreSQL et les autres. Un seul contexte oublié rouvre la faille.
- Ajouter une règle WAF et laisser le code tel quel est un contrôle compensatoire, utile en défense en profondeur, mais qui filtre le trafic par motifs et se contourne couramment avec des commentaires, des changements de casse et de l'encodage. Le code vulnérable part quand même en production.
- Une limite de 100 caractères ne sert à rien :
' OR 1=1--et la plupart des charges d'exfiltration tiennent largement sous toute limite raisonnable.
Ce que l'examinateur cherche à évaluer
Il veut voir que vous corrigez la classe de bug à la bonne couche plutôt que de recourir à un filtre ou à un équipement. Une bonne réponse cite d'abord le paramétrage, traite la validation des entrées et le WAF comme des couches supplémentaires (jamais le correctif), et connaît le cas limite : les variables de liaison ne peuvent pas paramétrer des identifiants comme les noms de table ou de colonne, qui doivent donc être validés contre une liste d'autorisation stricte.
Questions de suivi probables
- Comment les requêtes paramétrées empêchent-elles concrètement l'analyseur de traiter la saisie comme du code ?
- Où les instructions préparées n'aident-elles PAS — par exemple, pour des noms de table ou de colonne dynamiques ?
- Comment déploieriez-vous cette correction en toute sécurité sur une vaste base de code héritée ?