Injections : SQL, commandes, templates
L'injection reste n°1 (OWASP A03) après 25 ans : parce qu'elle naît d'une habitude (concaténer) pas d'une technologie.
Prérequis (cursus dev) : injections, XSS et CSRF ; cours SQL (cursus BDD).
Pourquoi
L'injection reste n°1 (OWASP A03) après 25 ans : parce qu'elle naît d'une habitude (concaténer) pas d'une technologie. Une règle unique l'élimine — à condition de l'appliquer partout, y compris là où « c'est interne ».
Concepts
- Principe : données ≠ code, toujours. Concaténer une entrée dans SQL/shell/template = exécuter l'entrée. La parade universelle : paramétrer (la donnée voyage séparée de l'instruction).
- SQL : requêtes paramétrées (
$1,?) + ORM qui paramètre (vérifier les.raw()!). Jamais de f-string dans du SQL. - Commandes OS :
child_process.exec(userInput)= shell offert. Parade :execFile+ args (pas de shell) ou bannir l'appel système (lib native). - SSTI / templates / LDAP / XPath / CSV : même famille (
{7*7}qui rend 49 = moteur exécuté ; formule Excel=CMD(à l'export). Chaque interpréteur a son injection.
Exemple : le test qui prouve
' OR '1'='1 → login sans mot de passe ? → injection SQL
{7*7} → rend 49 ? → SSTI
; id → exécuté ? → injection shell
Tester en recette, pas découvrir en prod. Et gitleaks + revue des .raw()/exec( en CI.
Cas réel
Export CSV « inoffensif » : cellule =cmd|'/c calc'!A0 exécutée à l'ouverture chez un client sous Windows (DDE). Correctif : préfixer les cellules à risque (') + documenter. L'injection vit aussi dans Excel.
Pièges
- « C'est interne/admin, pas besoin » : l'insider et le XSS-to-admin existent. Paramétrer partout, sans exception.
- ORM = protégé (toujours) : faux dès
.raw(),orderBy(input),find({where: JSON.parse(input)}). Auditer les échappatoires. - Échapper au lieu de paramétrer : l'échappement rate un contexte sur deux. Paramétrer d'abord, échapper en dernier recours documenté.
À retenir
Données ≠ code, toujours ; paramétrer (SQL, shell, templates) ; tester avec les 3 payloads ; auditer les .raw()/exec(.