🧬 SQL Injection — Guide cybersécurité ultra détaillé
Guide IDEO‑Lab en thème clair : comprendre, prévenir, tester, détecter et industrialiser la défense contre SQL Injection dans les applications web, APIs, backends, jobs et systèmes legacy.
Vue d’ensemble SQL Injection
Comprendre la vulnérabilité, son impact, son actualité et sa place dans les risques applicatifs modernes.
FondamentauxOWASPImpactDonnées vs commandes
Modèle mental central : une entrée utilisateur ne doit jamais devenir une instruction SQL.
Data/CodeInterpreterRisqueAnatomie d’une faille
Décomposer le flux HTTP → application → requête → base → réponse pour trouver la racine SQLi.
FlowRequêteDBTypes de SQLi
Union, error-based, blind, time-based, stacked, second-order, stored procedures, out-of-band.
UnionBlindSecond-orderBlind SQL Injection
Comprendre les attaques par inférence sans fuite directe de données.
BooleanTimeInferenceSecond-order SQLi
Quand une donnée stockée devient dangereuse plus tard dans un autre contexte SQL.
StockéeRéutiliséeWorkflowSurfaces d’entrée
Paramètres GET/POST, JSON, headers, cookies, GraphQL, search, exports, jobs et imports.
APIBatchAdminImpacts métier
Lecture, modification, suppression, contournement d’authentification, pivot, fuite RGPD, crise réputationnelle.
DonnéesBusinessRGPDOWASP & référentiels
Top 10, WSTG, Cheat Sheets, ASVS : comment les utiliser concrètement.
OWASPWSTGASVSRequêtes paramétrées
Prepared statements, binding, placeholders et séparation stricte SQL/valeurs.
PreparedBindingSafe APIORM & query builders
Comprendre ce que l’ORM protège réellement et où il ne protège plus.
ORMRaw SQLQuery builderSQL dynamique contrôlé
ORDER BY, filtres, colonnes, rapports, exports : allow-list et mapping serveur.
Allow-listORDER BYReportsErreurs, logs et messages
Éviter les fuites tout en gardant des logs utiles pour le diagnostic.
ErrorsLogsLeakageMoindre privilège DB
Limiter l’impact : comptes, rôles, vues, procédures, segmentation et secrets.
Least privilegeRolesSecretsTests SQLi contrôlés
Méthodologie WSTG : revue, SAST, DAST, tests manuels autorisés et preuve de correction.
WSTGDASTSASTCI/CD & DevSecOps
Intégrer SQLi dans la Definition of Done, pipelines et qualité de code.
CI/CDQuality gatesDevSecOpsWAF / WAAP
Détection et blocage complémentaires : règles, scoring, faux positifs, tuning, limites.
WAFWAAPTuningDétection SOC/SIEM
Corréler WAF, app, DB, IAM et données pour détecter les tentatives et exploitations.
SIEMDB auditCorrelationRéponse à incident
Qualifier, contenir, corriger, notifier, apprendre et ajouter les tests de régression.
IRForensicsPost-mortemFocus Django/Python
Patterns sécurisés pour ORM Django, raw SQL, psycopg, SQLAlchemy et revues de code.
DjangoPythonORMSnippets multi-langages
Node, Java, PHP, .NET, Go : repères de paramétrisation par stack.
NodeJavaPHPRemédiation legacy
Transformer une base ancienne vulnérable sans tout casser : inventaire, priorisation, patchs sûrs.
LegacyPriorisationPatchFormation développeurs
Ateliers, kata, revues, checklists, anti-patterns et culture secure coding.
TrainingKataReviewCheat-sheet & roadmap
Résumé opérationnel, checklists, roadmap 30/60/90 jours et référentiels.
Cheat-sheetRoadmapRefsPrévention immédiate
- Prepared statements pour toutes les valeurs.
- Aucune concaténation SQL avec input non fiable.
- Allow-list serveur pour colonnes, tris, noms de tables, directions.
- Compte DB à privilèges minimaux.
- Messages d’erreur génériques côté client.
SELECT id, email FROM users WHERE email = ? params = [email]
Review de code
| Zone | Signal | Action |
|---|---|---|
| Concaténation | rechercher +, f-string, template literal, format | remplacer par binding |
| Raw SQL | justification + test obligatoire | préférer ORM ou paramètres |
| ORDER BY dynamique | input libre interdit | mapping allow-list |
| Procédure stockée | EXEC dynamique suspect | procédure paramétrée |
Tests contrôlés
- Tester uniquement sur périmètre autorisé.
- Créer jeux de données non sensibles.
- Coupler SAST, DAST et revue manuelle.
- Valider la correction par test de régression.
- Documenter route, paramètre, preuve et patch.
Détection
| Source | Signal | Action |
|---|---|---|
| WAF | score injection, répétition payloads | corréler avec app |
| App | erreurs 500, exceptions SQL | masquer client, log interne |
| DB | syntax errors, requêtes longues | request-id |
| Données | volume anormal lecture/export | alerte exfiltration |
Réponse incident
- Qualifier route, paramètre, fenêtre et user/IP.
- Contenir sans masquer le correctif code.
- Analyser accès données et privilèges.
- Corriger cause racine et endpoints similaires.
- Ajouter tests, règles review et post-mortem.
Références solides
| Ressource | Apport | Usage |
|---|---|---|
| OWASP SQL Injection Prevention Cheat Sheet | Requêtes préparées, procédures stockées, allow-list, échappement en dernier recours | à utiliser comme base de politique dev |
| OWASP Query Parameterization Cheat Sheet | Exemples de paramétrisation multi-langages | à intégrer aux formations |
| OWASP Top 10 2025 A05 Injection | Positionnement injection dans les risques web critiques | à relier au programme AppSec |
| OWASP WSTG SQL Injection | Méthodologie de test contrôlé | à cadrer en environnement autorisé |
| PortSwigger Web Security Academy | Explications et labs pédagogiques | à utiliser en training encadré |
Tests responsables
- Tester uniquement les environnements autorisés.
- Conserver les preuves utiles sans exposer de données sensibles.
- Créer des tests de régression après chaque correction.
- Documenter le périmètre, les comptes, les données et les fenêtres de test.
Règles de code
Policy SQLi - Prepared statements mandatory for all values. - Raw SQL requires security review. - Dynamic identifiers require server-side allow-list. - No SQL string concatenation with untrusted input. - DB account follows least privilege. - Tests cover repository and vulnerable patterns.
Roadmap 30/60/90 jours
30 jours
- Inventaire raw SQL.
- Formation rapide dev.
- Règles de review.
- Logging erreurs DB sécurisé.
60 jours
- Patch prioritaire endpoints critiques.
- Tests SAST/DAST contrôlés.
- Moindre privilège DB.
- Règles WAF ciblées.
90 jours
- Couverture CI/CD.
- Tableaux de bord SOC.
- Exercices incident.
- Dette legacy priorisée.
Comprendre la vulnérabilité, son impact, son actualité et sa place dans les risques applicatifs modernes.
Objectifs pédagogiques
- Comprendre le mécanisme sans tomber dans la simple liste de payloads.
- Savoir reconnaître les zones à risque dans le code et l’architecture.
- Appliquer une défense en profondeur : code, DB, WAF/WAAP, tests, SOC.
- Transformer le sujet en pratiques industrialisées dans le cycle de développement.
Points de vigilance
| Point | Détail | Bon réflexe |
|---|---|---|
| Cause racine | entrée interprétée comme SQL | séparation données / commandes |
| Correction durable | requêtes paramétrées et allow-list | pas de concaténation |
| Réduction impact | moindre privilège DB | segmentation et audit |
| Contrôle continu | tests + logs + WAF + SOC | feedback loop |
Modèle mental
Vue d’ensemble SQL Injection | +--> conception sûre +--> code paramétré +--> DB à privilèges minimaux +--> tests contrôlés +--> détection et réponse
Vue d’ensemble SQL Injection — familles de SQL Injection
| Famille | Principe | Défense prioritaire |
|---|---|---|
| In-band / classique | Résultat ou erreur observable dans la réponse HTTP | prioriser correction du code et masquage erreurs |
| Union-based | Tentative de combiner un résultat contrôlé avec la requête originale | paramétrisation + contrôle strict des colonnes exposées |
| Error-based | Exploitation des erreurs DB pour révéler structure ou données | messages génériques + logs internes |
| Blind boolean | Inférence par différence de réponse vrai/faux | tests automatisés autorisés + monitoring anomalies |
| Blind time-based | Inférence par délai volontaire | timeouts, détection latence anormale, requêtes paramétrées |
| Second-order | Charge stockée puis réutilisée plus tard dans une requête vulnérable | paramétriser aussi les données déjà stockées |
| Stored procedure unsafe | Procédure stockée qui concatène dynamiquement | procédures paramétrées sans EXEC dynamique non contrôlé |
| NoSQL-like analog | Même famille conceptuelle avec moteurs non SQL | séparer données et opérateurs |
' OR '1'='1 -- exemple pédagogique de test en lab
UNION SELECT ... -- à comprendre, pas à utiliser hors environnement autorisé
donnée stockée -> requête ultérieure -> second-order SQLi
Vue d’ensemble SQL Injection — prévention robuste
La défense centrale consiste à écrire une requête dont la structure SQL est connue à l’avance, puis à transmettre les valeurs séparément au driver. Le driver gère l’encodage et la liaison des paramètres sans transformer la valeur en fragment SQL.
# Python / psycopg - correct
cursor.execute(
"SELECT id, email FROM users WHERE email = %s",
(email,)
)
# À éviter
cursor.execute("SELECT id FROM users WHERE email = '" + email + "'")Ce qui complète la paramétrisation
- Allow-list pour les noms de colonnes, tris, directions, types de filtres.
- Moindre privilège : compte applicatif limité aux opérations nécessaires.
- Transactions courtes et requêtes lisibles.
- Logs internes utiles sans fuite de SQL brut côté client.
- Tests automatisés unitaires, intégration, DAST contrôlé, revue SAST.
| Élément | Technique sûre | Règle |
|---|---|---|
| Valeurs | paramètres liés | OK |
| Identifiants SQL | allow-list stricte | jamais depuis input libre |
| ORDER BY | mapping champ public -> colonne interne | direction ASC/DESC whitelistée |
| LIMIT/OFFSET | conversion numérique + bornes | pas de texte libre |
Vue d’ensemble SQL Injection — stratégie de test autorisée
Tester SQLi ne consiste pas à lancer des attaques au hasard. Une démarche professionnelle part d’une cartographie des entrées, puis combine revue de code, tests unitaires de repositories, SAST, DAST sur environnement de test, et validation manuelle encadrée.
- Lister les endpoints, paramètres, filtres, headers, payloads JSON, jobs et imports qui atteignent la DB.
- Identifier les requêtes dynamiques, raw SQL, procédures stockées, query builders et générateurs de rapports.
- Vérifier les paramètres liés, allow-lists et bornes numériques.
- Exécuter les tests uniquement sur environnement autorisé avec données non sensibles.
- Créer des tickets correctifs rattachés aux lignes de code et aux routes concernées.
Cas de tests défensifs
| Zone | Objectif de test | Contrôle attendu |
|---|---|---|
| Login | ne pas différencier erreur SQL / auth invalide | réponse générique + logs internes |
| Recherche | requête paramétrée même avec LIKE | concaténer le wildcard côté valeur, pas SQL |
| Tri | champ et direction par allow-list | mapping serveur |
| Export | mêmes protections que l’API interactive | pas de contournement batch |
| Admin | raw SQL encore plus contrôlé | review obligatoire |
Vue d’ensemble SQL Injection — détection et exploitation SOC
| Source | Signal | Action SOC |
|---|---|---|
| HTTP | pics de 4xx/5xx, paramètres atypiques, erreurs applicatives | alerte corrélée route + user + IP |
| WAF/WAAP | règles injection, score anomalie, répétition payloads | distinguer scan, test interne, attaque |
| DB | erreurs syntaxe, requêtes longues, requêtes inhabituelles | lier à request-id si possible |
| IAM | compte applicatif utilisé hors chemin normal | alerter sur privilèges anormaux |
| Données | volumétrie de lecture/export, accès tables sensibles | détection exfiltration |
request_id=abc123 route=/api/search status=500 waf_rule=SQLI_DETECTED db_error=syntax_error user_id=42
- Corréler les événements avec un identifiant de requête.
- Ne pas se limiter au WAF : une SQLi peut être exploitée via API, batch, mobile ou admin interne.
- Créer un playbook : qualifier, isoler, préserver les preuves, corriger la cause, surveiller la récidive.
- Transformer les incidents en tests de régression et règles de revue de code.
Vue d’ensemble SQL Injection — playbook incident SQLi
1. Qualification
- Identifier route, méthode, paramètre, compte utilisateur, IP, fenêtre temporelle.
- Distinguer test interne, scan externe, exploitation probable.
- Préserver logs WAF, app, reverse proxy, DB et audit.
2. Containment
- Désactiver ou filtrer la route si nécessaire.
- Réduire privilèges du compte applicatif si trop large.
- Ajouter règle WAF temporaire ciblée sans masquer le correctif code.
3. Éradication
- Corriger concaténation/raw SQL.
- Ajouter tests de régression.
- Revoir endpoints similaires.
- Déployer avec rollback possible.
| Sujet | À documenter | Livrable |
|---|---|---|
| Preuves | logs horodatés, payloads, réponses, erreurs DB, traces | chaîne de conservation |
| Données | tables lues/modifiées, exports, comptes affectés | analyse d’impact |
| Communication | juridique, DPO, RSSI, métiers, client si nécessaire | message factuel |
| Post-mortem | racine, délai détection, tests manquants, ownership | plan d’actions |
Vue d’ensemble SQL Injection — gouvernance et industrialisation
- Définir une politique officielle : requêtes paramétrées obligatoires, raw SQL justifié et revu.
- Ajouter des règles de revue : concaténation SQL interdite, tri/colonnes par allow-list.
- Inscrire SQLi dans le threat modeling des features : recherche, reporting, filtres avancés, exports.
- Créer un module de formation développeur avec exemples du stack réel de l’entreprise.
- Mesurer les progrès : dette raw SQL, couverture tests, incidents, temps de correction.
Definition of Done SQLi-safe [ ] aucune concaténation de données dans SQL [ ] paramètres liés pour toutes les valeurs [ ] allow-list pour identifiants SQL dynamiques [ ] tests unitaires repository [ ] logs sans fuite de SQL sensible [ ] privilèges DB minimaux
Vue d’ensemble SQL Injection — analyse détaillée
Cette section relie le sujet à la chaîne complète de sécurité applicative : conception, développement, test, déploiement, supervision et réponse à incident. SQL Injection reste un bon exemple de vulnérabilité apparemment “ancienne” mais durable, car elle naît d’un défaut fondamental de séparation entre données et instructions.
- Identifier les entrées qui atteignent la base.
- Séparer valeurs et structure SQL.
- Limiter les privilèges côté base.
- Ajouter tests et contrôles CI/CD.
- Superviser les signaux applicatifs, WAF et DB.
| Point | Détail | Bon réflexe |
|---|---|---|
| Conception | réduire SQL dynamique | patterns repository sûrs |
| Développement | paramètres liés | revue de code systématique |
| Tests | SAST/DAST/lab | preuve corrigée |
| Production | observabilité + WAF | détection rapide |
Modèle mental central : une entrée utilisateur ne doit jamais devenir une instruction SQL.
Objectifs pédagogiques
- Comprendre le mécanisme sans tomber dans la simple liste de payloads.
- Savoir reconnaître les zones à risque dans le code et l’architecture.
- Appliquer une défense en profondeur : code, DB, WAF/WAAP, tests, SOC.
- Transformer le sujet en pratiques industrialisées dans le cycle de développement.
Points de vigilance
| Point | Détail | Bon réflexe |
|---|---|---|
| Cause racine | entrée interprétée comme SQL | séparation données / commandes |
| Correction durable | requêtes paramétrées et allow-list | pas de concaténation |
| Réduction impact | moindre privilège DB | segmentation et audit |
| Contrôle continu | tests + logs + WAF + SOC | feedback loop |
Modèle mental
Données vs commandes | +--> conception sûre +--> code paramétré +--> DB à privilèges minimaux +--> tests contrôlés +--> détection et réponse
Données vs commandes — prévention robuste
La défense centrale consiste à écrire une requête dont la structure SQL est connue à l’avance, puis à transmettre les valeurs séparément au driver. Le driver gère l’encodage et la liaison des paramètres sans transformer la valeur en fragment SQL.
# Python / psycopg - correct
cursor.execute(
"SELECT id, email FROM users WHERE email = %s",
(email,)
)
# À éviter
cursor.execute("SELECT id FROM users WHERE email = '" + email + "'")Ce qui complète la paramétrisation
- Allow-list pour les noms de colonnes, tris, directions, types de filtres.
- Moindre privilège : compte applicatif limité aux opérations nécessaires.
- Transactions courtes et requêtes lisibles.
- Logs internes utiles sans fuite de SQL brut côté client.
- Tests automatisés unitaires, intégration, DAST contrôlé, revue SAST.
| Élément | Technique sûre | Règle |
|---|---|---|
| Valeurs | paramètres liés | OK |
| Identifiants SQL | allow-list stricte | jamais depuis input libre |
| ORDER BY | mapping champ public -> colonne interne | direction ASC/DESC whitelistée |
| LIMIT/OFFSET | conversion numérique + bornes | pas de texte libre |
Données vs commandes — exemples de code sécurisé
Django ORM
# Bon : ORM filtre les valeurs
user = User.objects.filter(email=email).first()
# Raw SQL : paramètres obligatoires
User.objects.raw(
"SELECT * FROM app_user WHERE email = %s",
[email]
)Node.js / pg
const result = await client.query( 'SELECT id, email FROM users WHERE email = $1', [email] );
Java / JDBC
PreparedStatement ps = conn.prepareStatement( "SELECT id,email FROM users WHERE email = ?" ); ps.setString(1, email); ResultSet rs = ps.executeQuery();
PHP / PDO
$stmt = $pdo->prepare( 'SELECT id,email FROM users WHERE email = :email' ); $stmt->execute(['email' => $email]);
.NET
using var cmd = new SqlCommand(
"SELECT Id, Email FROM Users WHERE Email = @email", conn);
cmd.Parameters.AddWithValue("@email", email);Go / database/sql
row := db.QueryRowContext(ctx, "SELECT id,email FROM users WHERE email = ?", email, )
Données vs commandes — stratégie de test autorisée
Tester SQLi ne consiste pas à lancer des attaques au hasard. Une démarche professionnelle part d’une cartographie des entrées, puis combine revue de code, tests unitaires de repositories, SAST, DAST sur environnement de test, et validation manuelle encadrée.
- Lister les endpoints, paramètres, filtres, headers, payloads JSON, jobs et imports qui atteignent la DB.
- Identifier les requêtes dynamiques, raw SQL, procédures stockées, query builders et générateurs de rapports.
- Vérifier les paramètres liés, allow-lists et bornes numériques.
- Exécuter les tests uniquement sur environnement autorisé avec données non sensibles.
- Créer des tickets correctifs rattachés aux lignes de code et aux routes concernées.
Cas de tests défensifs
| Zone | Objectif de test | Contrôle attendu |
|---|---|---|
| Login | ne pas différencier erreur SQL / auth invalide | réponse générique + logs internes |
| Recherche | requête paramétrée même avec LIKE | concaténer le wildcard côté valeur, pas SQL |
| Tri | champ et direction par allow-list | mapping serveur |
| Export | mêmes protections que l’API interactive | pas de contournement batch |
| Admin | raw SQL encore plus contrôlé | review obligatoire |
Données vs commandes — analyse détaillée
Cette section relie le sujet à la chaîne complète de sécurité applicative : conception, développement, test, déploiement, supervision et réponse à incident. SQL Injection reste un bon exemple de vulnérabilité apparemment “ancienne” mais durable, car elle naît d’un défaut fondamental de séparation entre données et instructions.
- Identifier les entrées qui atteignent la base.
- Séparer valeurs et structure SQL.
- Limiter les privilèges côté base.
- Ajouter tests et contrôles CI/CD.
- Superviser les signaux applicatifs, WAF et DB.
| Point | Détail | Bon réflexe |
|---|---|---|
| Conception | réduire SQL dynamique | patterns repository sûrs |
| Développement | paramètres liés | revue de code systématique |
| Tests | SAST/DAST/lab | preuve corrigée |
| Production | observabilité + WAF | détection rapide |
Données vs commandes — détection et exploitation SOC
| Source | Signal | Action SOC |
|---|---|---|
| HTTP | pics de 4xx/5xx, paramètres atypiques, erreurs applicatives | alerte corrélée route + user + IP |
| WAF/WAAP | règles injection, score anomalie, répétition payloads | distinguer scan, test interne, attaque |
| DB | erreurs syntaxe, requêtes longues, requêtes inhabituelles | lier à request-id si possible |
| IAM | compte applicatif utilisé hors chemin normal | alerter sur privilèges anormaux |
| Données | volumétrie de lecture/export, accès tables sensibles | détection exfiltration |
request_id=abc123 route=/api/search status=500 waf_rule=SQLI_DETECTED db_error=syntax_error user_id=42
- Corréler les événements avec un identifiant de requête.
- Ne pas se limiter au WAF : une SQLi peut être exploitée via API, batch, mobile ou admin interne.
- Créer un playbook : qualifier, isoler, préserver les preuves, corriger la cause, surveiller la récidive.
- Transformer les incidents en tests de régression et règles de revue de code.
Données vs commandes — gouvernance et industrialisation
- Définir une politique officielle : requêtes paramétrées obligatoires, raw SQL justifié et revu.
- Ajouter des règles de revue : concaténation SQL interdite, tri/colonnes par allow-list.
- Inscrire SQLi dans le threat modeling des features : recherche, reporting, filtres avancés, exports.
- Créer un module de formation développeur avec exemples du stack réel de l’entreprise.
- Mesurer les progrès : dette raw SQL, couverture tests, incidents, temps de correction.
Definition of Done SQLi-safe [ ] aucune concaténation de données dans SQL [ ] paramètres liés pour toutes les valeurs [ ] allow-list pour identifiants SQL dynamiques [ ] tests unitaires repository [ ] logs sans fuite de SQL sensible [ ] privilèges DB minimaux
Données vs commandes — playbook incident SQLi
1. Qualification
- Identifier route, méthode, paramètre, compte utilisateur, IP, fenêtre temporelle.
- Distinguer test interne, scan externe, exploitation probable.
- Préserver logs WAF, app, reverse proxy, DB et audit.
2. Containment
- Désactiver ou filtrer la route si nécessaire.
- Réduire privilèges du compte applicatif si trop large.
- Ajouter règle WAF temporaire ciblée sans masquer le correctif code.
3. Éradication
- Corriger concaténation/raw SQL.
- Ajouter tests de régression.
- Revoir endpoints similaires.
- Déployer avec rollback possible.
| Sujet | À documenter | Livrable |
|---|---|---|
| Preuves | logs horodatés, payloads, réponses, erreurs DB, traces | chaîne de conservation |
| Données | tables lues/modifiées, exports, comptes affectés | analyse d’impact |
| Communication | juridique, DPO, RSSI, métiers, client si nécessaire | message factuel |
| Post-mortem | racine, délai détection, tests manquants, ownership | plan d’actions |
Décomposer le flux HTTP → application → requête → base → réponse pour trouver la racine SQLi.
Objectifs pédagogiques
- Comprendre le mécanisme sans tomber dans la simple liste de payloads.
- Savoir reconnaître les zones à risque dans le code et l’architecture.
- Appliquer une défense en profondeur : code, DB, WAF/WAAP, tests, SOC.
- Transformer le sujet en pratiques industrialisées dans le cycle de développement.
Points de vigilance
| Point | Détail | Bon réflexe |
|---|---|---|
| Cause racine | entrée interprétée comme SQL | séparation données / commandes |
| Correction durable | requêtes paramétrées et allow-list | pas de concaténation |
| Réduction impact | moindre privilège DB | segmentation et audit |
| Contrôle continu | tests + logs + WAF + SOC | feedback loop |
Modèle mental
Anatomie d’une faille | +--> conception sûre +--> code paramétré +--> DB à privilèges minimaux +--> tests contrôlés +--> détection et réponse
Anatomie d’une faille — familles de SQL Injection
| Famille | Principe | Défense prioritaire |
|---|---|---|
| In-band / classique | Résultat ou erreur observable dans la réponse HTTP | prioriser correction du code et masquage erreurs |
| Union-based | Tentative de combiner un résultat contrôlé avec la requête originale | paramétrisation + contrôle strict des colonnes exposées |
| Error-based | Exploitation des erreurs DB pour révéler structure ou données | messages génériques + logs internes |
| Blind boolean | Inférence par différence de réponse vrai/faux | tests automatisés autorisés + monitoring anomalies |
| Blind time-based | Inférence par délai volontaire | timeouts, détection latence anormale, requêtes paramétrées |
| Second-order | Charge stockée puis réutilisée plus tard dans une requête vulnérable | paramétriser aussi les données déjà stockées |
| Stored procedure unsafe | Procédure stockée qui concatène dynamiquement | procédures paramétrées sans EXEC dynamique non contrôlé |
| NoSQL-like analog | Même famille conceptuelle avec moteurs non SQL | séparer données et opérateurs |
' OR '1'='1 -- exemple pédagogique de test en lab
UNION SELECT ... -- à comprendre, pas à utiliser hors environnement autorisé
donnée stockée -> requête ultérieure -> second-order SQLi
Anatomie d’une faille — stratégie de test autorisée
Tester SQLi ne consiste pas à lancer des attaques au hasard. Une démarche professionnelle part d’une cartographie des entrées, puis combine revue de code, tests unitaires de repositories, SAST, DAST sur environnement de test, et validation manuelle encadrée.
- Lister les endpoints, paramètres, filtres, headers, payloads JSON, jobs et imports qui atteignent la DB.
- Identifier les requêtes dynamiques, raw SQL, procédures stockées, query builders et générateurs de rapports.
- Vérifier les paramètres liés, allow-lists et bornes numériques.
- Exécuter les tests uniquement sur environnement autorisé avec données non sensibles.
- Créer des tickets correctifs rattachés aux lignes de code et aux routes concernées.
Cas de tests défensifs
| Zone | Objectif de test | Contrôle attendu |
|---|---|---|
| Login | ne pas différencier erreur SQL / auth invalide | réponse générique + logs internes |
| Recherche | requête paramétrée même avec LIKE | concaténer le wildcard côté valeur, pas SQL |
| Tri | champ et direction par allow-list | mapping serveur |
| Export | mêmes protections que l’API interactive | pas de contournement batch |
| Admin | raw SQL encore plus contrôlé | review obligatoire |
Anatomie d’une faille — prévention robuste
La défense centrale consiste à écrire une requête dont la structure SQL est connue à l’avance, puis à transmettre les valeurs séparément au driver. Le driver gère l’encodage et la liaison des paramètres sans transformer la valeur en fragment SQL.
# Python / psycopg - correct
cursor.execute(
"SELECT id, email FROM users WHERE email = %s",
(email,)
)
# À éviter
cursor.execute("SELECT id FROM users WHERE email = '" + email + "'")Ce qui complète la paramétrisation
- Allow-list pour les noms de colonnes, tris, directions, types de filtres.
- Moindre privilège : compte applicatif limité aux opérations nécessaires.
- Transactions courtes et requêtes lisibles.
- Logs internes utiles sans fuite de SQL brut côté client.
- Tests automatisés unitaires, intégration, DAST contrôlé, revue SAST.
| Élément | Technique sûre | Règle |
|---|---|---|
| Valeurs | paramètres liés | OK |
| Identifiants SQL | allow-list stricte | jamais depuis input libre |
| ORDER BY | mapping champ public -> colonne interne | direction ASC/DESC whitelistée |
| LIMIT/OFFSET | conversion numérique + bornes | pas de texte libre |
Anatomie d’une faille — exemples de code sécurisé
Django ORM
# Bon : ORM filtre les valeurs
user = User.objects.filter(email=email).first()
# Raw SQL : paramètres obligatoires
User.objects.raw(
"SELECT * FROM app_user WHERE email = %s",
[email]
)Node.js / pg
const result = await client.query( 'SELECT id, email FROM users WHERE email = $1', [email] );
Java / JDBC
PreparedStatement ps = conn.prepareStatement( "SELECT id,email FROM users WHERE email = ?" ); ps.setString(1, email); ResultSet rs = ps.executeQuery();
PHP / PDO
$stmt = $pdo->prepare( 'SELECT id,email FROM users WHERE email = :email' ); $stmt->execute(['email' => $email]);
.NET
using var cmd = new SqlCommand(
"SELECT Id, Email FROM Users WHERE Email = @email", conn);
cmd.Parameters.AddWithValue("@email", email);Go / database/sql
row := db.QueryRowContext(ctx, "SELECT id,email FROM users WHERE email = ?", email, )
Anatomie d’une faille — détection et exploitation SOC
| Source | Signal | Action SOC |
|---|---|---|
| HTTP | pics de 4xx/5xx, paramètres atypiques, erreurs applicatives | alerte corrélée route + user + IP |
| WAF/WAAP | règles injection, score anomalie, répétition payloads | distinguer scan, test interne, attaque |
| DB | erreurs syntaxe, requêtes longues, requêtes inhabituelles | lier à request-id si possible |
| IAM | compte applicatif utilisé hors chemin normal | alerter sur privilèges anormaux |
| Données | volumétrie de lecture/export, accès tables sensibles | détection exfiltration |
request_id=abc123 route=/api/search status=500 waf_rule=SQLI_DETECTED db_error=syntax_error user_id=42
- Corréler les événements avec un identifiant de requête.
- Ne pas se limiter au WAF : une SQLi peut être exploitée via API, batch, mobile ou admin interne.
- Créer un playbook : qualifier, isoler, préserver les preuves, corriger la cause, surveiller la récidive.
- Transformer les incidents en tests de régression et règles de revue de code.
Anatomie d’une faille — playbook incident SQLi
1. Qualification
- Identifier route, méthode, paramètre, compte utilisateur, IP, fenêtre temporelle.
- Distinguer test interne, scan externe, exploitation probable.
- Préserver logs WAF, app, reverse proxy, DB et audit.
2. Containment
- Désactiver ou filtrer la route si nécessaire.
- Réduire privilèges du compte applicatif si trop large.
- Ajouter règle WAF temporaire ciblée sans masquer le correctif code.
3. Éradication
- Corriger concaténation/raw SQL.
- Ajouter tests de régression.
- Revoir endpoints similaires.
- Déployer avec rollback possible.
| Sujet | À documenter | Livrable |
|---|---|---|
| Preuves | logs horodatés, payloads, réponses, erreurs DB, traces | chaîne de conservation |
| Données | tables lues/modifiées, exports, comptes affectés | analyse d’impact |
| Communication | juridique, DPO, RSSI, métiers, client si nécessaire | message factuel |
| Post-mortem | racine, délai détection, tests manquants, ownership | plan d’actions |
Anatomie d’une faille — analyse détaillée
Cette section relie le sujet à la chaîne complète de sécurité applicative : conception, développement, test, déploiement, supervision et réponse à incident. SQL Injection reste un bon exemple de vulnérabilité apparemment “ancienne” mais durable, car elle naît d’un défaut fondamental de séparation entre données et instructions.
- Identifier les entrées qui atteignent la base.
- Séparer valeurs et structure SQL.
- Limiter les privilèges côté base.
- Ajouter tests et contrôles CI/CD.
- Superviser les signaux applicatifs, WAF et DB.
| Point | Détail | Bon réflexe |
|---|---|---|
| Conception | réduire SQL dynamique | patterns repository sûrs |
| Développement | paramètres liés | revue de code systématique |
| Tests | SAST/DAST/lab | preuve corrigée |
| Production | observabilité + WAF | détection rapide |
Union, error-based, blind, time-based, stacked, second-order, stored procedures, out-of-band.
Objectifs pédagogiques
- Comprendre le mécanisme sans tomber dans la simple liste de payloads.
- Savoir reconnaître les zones à risque dans le code et l’architecture.
- Appliquer une défense en profondeur : code, DB, WAF/WAAP, tests, SOC.
- Transformer le sujet en pratiques industrialisées dans le cycle de développement.
Points de vigilance
| Point | Détail | Bon réflexe |
|---|---|---|
| Cause racine | entrée interprétée comme SQL | séparation données / commandes |
| Correction durable | requêtes paramétrées et allow-list | pas de concaténation |
| Réduction impact | moindre privilège DB | segmentation et audit |
| Contrôle continu | tests + logs + WAF + SOC | feedback loop |
Modèle mental
Types de SQLi | +--> conception sûre +--> code paramétré +--> DB à privilèges minimaux +--> tests contrôlés +--> détection et réponse
Types de SQLi — lecture technique
Une injection SQL apparaît lorsqu’une application mélange une donnée fournie par l’utilisateur avec une instruction SQL au lieu de maintenir une séparation stricte entre le code de la requête et les valeurs. Le problème n’est pas le caractère spécial lui-même : c’est le fait que la base interprète une partie de l’entrée comme de la logique SQL.
| Point | Détail | Bon réflexe |
|---|---|---|
| Symptôme | Concaténation de chaînes, interpolation, requête dynamique non maîtrisée | remplacer par requête paramétrée |
| Racine | Confusion donnée / commande | forcer la séparation dès la couche d’accès DB |
| Amplification | Messages d’erreur trop bavards, compte DB trop privilégié | réduire privilèges et surfaces de fuite |
| Détection | Erreurs SQL, variations de temps, anomalies de volume, patterns suspects | corréler applicatif, DB, WAF et SIEM |
Chaîne logique
Entrée HTTP / API / job | v Validation métier | v Construction requête SQL | +--> mauvais : concaténation/interpolation | +--> bon : SQL fixe + paramètres liés | v DB exécute uniquement l’instruction prévue
Types de SQLi — stratégie de test autorisée
Tester SQLi ne consiste pas à lancer des attaques au hasard. Une démarche professionnelle part d’une cartographie des entrées, puis combine revue de code, tests unitaires de repositories, SAST, DAST sur environnement de test, et validation manuelle encadrée.
- Lister les endpoints, paramètres, filtres, headers, payloads JSON, jobs et imports qui atteignent la DB.
- Identifier les requêtes dynamiques, raw SQL, procédures stockées, query builders et générateurs de rapports.
- Vérifier les paramètres liés, allow-lists et bornes numériques.
- Exécuter les tests uniquement sur environnement autorisé avec données non sensibles.
- Créer des tickets correctifs rattachés aux lignes de code et aux routes concernées.
Cas de tests défensifs
| Zone | Objectif de test | Contrôle attendu |
|---|---|---|
| Login | ne pas différencier erreur SQL / auth invalide | réponse générique + logs internes |
| Recherche | requête paramétrée même avec LIKE | concaténer le wildcard côté valeur, pas SQL |
| Tri | champ et direction par allow-list | mapping serveur |
| Export | mêmes protections que l’API interactive | pas de contournement batch |
| Admin | raw SQL encore plus contrôlé | review obligatoire |
Types de SQLi — détection et exploitation SOC
| Source | Signal | Action SOC |
|---|---|---|
| HTTP | pics de 4xx/5xx, paramètres atypiques, erreurs applicatives | alerte corrélée route + user + IP |
| WAF/WAAP | règles injection, score anomalie, répétition payloads | distinguer scan, test interne, attaque |
| DB | erreurs syntaxe, requêtes longues, requêtes inhabituelles | lier à request-id si possible |
| IAM | compte applicatif utilisé hors chemin normal | alerter sur privilèges anormaux |
| Données | volumétrie de lecture/export, accès tables sensibles | détection exfiltration |
request_id=abc123 route=/api/search status=500 waf_rule=SQLI_DETECTED db_error=syntax_error user_id=42
- Corréler les événements avec un identifiant de requête.
- Ne pas se limiter au WAF : une SQLi peut être exploitée via API, batch, mobile ou admin interne.
- Créer un playbook : qualifier, isoler, préserver les preuves, corriger la cause, surveiller la récidive.
- Transformer les incidents en tests de régression et règles de revue de code.
Types de SQLi — prévention robuste
La défense centrale consiste à écrire une requête dont la structure SQL est connue à l’avance, puis à transmettre les valeurs séparément au driver. Le driver gère l’encodage et la liaison des paramètres sans transformer la valeur en fragment SQL.
# Python / psycopg - correct
cursor.execute(
"SELECT id, email FROM users WHERE email = %s",
(email,)
)
# À éviter
cursor.execute("SELECT id FROM users WHERE email = '" + email + "'")Ce qui complète la paramétrisation
- Allow-list pour les noms de colonnes, tris, directions, types de filtres.
- Moindre privilège : compte applicatif limité aux opérations nécessaires.
- Transactions courtes et requêtes lisibles.
- Logs internes utiles sans fuite de SQL brut côté client.
- Tests automatisés unitaires, intégration, DAST contrôlé, revue SAST.
| Élément | Technique sûre | Règle |
|---|---|---|
| Valeurs | paramètres liés | OK |
| Identifiants SQL | allow-list stricte | jamais depuis input libre |
| ORDER BY | mapping champ public -> colonne interne | direction ASC/DESC whitelistée |
| LIMIT/OFFSET | conversion numérique + bornes | pas de texte libre |
Types de SQLi — playbook incident SQLi
1. Qualification
- Identifier route, méthode, paramètre, compte utilisateur, IP, fenêtre temporelle.
- Distinguer test interne, scan externe, exploitation probable.
- Préserver logs WAF, app, reverse proxy, DB et audit.
2. Containment
- Désactiver ou filtrer la route si nécessaire.
- Réduire privilèges du compte applicatif si trop large.
- Ajouter règle WAF temporaire ciblée sans masquer le correctif code.
3. Éradication
- Corriger concaténation/raw SQL.
- Ajouter tests de régression.
- Revoir endpoints similaires.
- Déployer avec rollback possible.
| Sujet | À documenter | Livrable |
|---|---|---|
| Preuves | logs horodatés, payloads, réponses, erreurs DB, traces | chaîne de conservation |
| Données | tables lues/modifiées, exports, comptes affectés | analyse d’impact |
| Communication | juridique, DPO, RSSI, métiers, client si nécessaire | message factuel |
| Post-mortem | racine, délai détection, tests manquants, ownership | plan d’actions |
Types de SQLi — analyse détaillée
Cette section relie le sujet à la chaîne complète de sécurité applicative : conception, développement, test, déploiement, supervision et réponse à incident. SQL Injection reste un bon exemple de vulnérabilité apparemment “ancienne” mais durable, car elle naît d’un défaut fondamental de séparation entre données et instructions.
- Identifier les entrées qui atteignent la base.
- Séparer valeurs et structure SQL.
- Limiter les privilèges côté base.
- Ajouter tests et contrôles CI/CD.
- Superviser les signaux applicatifs, WAF et DB.
| Point | Détail | Bon réflexe |
|---|---|---|
| Conception | réduire SQL dynamique | patterns repository sûrs |
| Développement | paramètres liés | revue de code systématique |
| Tests | SAST/DAST/lab | preuve corrigée |
| Production | observabilité + WAF | détection rapide |
Types de SQLi — gouvernance et industrialisation
- Définir une politique officielle : requêtes paramétrées obligatoires, raw SQL justifié et revu.
- Ajouter des règles de revue : concaténation SQL interdite, tri/colonnes par allow-list.
- Inscrire SQLi dans le threat modeling des features : recherche, reporting, filtres avancés, exports.
- Créer un module de formation développeur avec exemples du stack réel de l’entreprise.
- Mesurer les progrès : dette raw SQL, couverture tests, incidents, temps de correction.
Definition of Done SQLi-safe [ ] aucune concaténation de données dans SQL [ ] paramètres liés pour toutes les valeurs [ ] allow-list pour identifiants SQL dynamiques [ ] tests unitaires repository [ ] logs sans fuite de SQL sensible [ ] privilèges DB minimaux
Comprendre les attaques par inférence sans fuite directe de données.
Objectifs pédagogiques
- Comprendre le mécanisme sans tomber dans la simple liste de payloads.
- Savoir reconnaître les zones à risque dans le code et l’architecture.
- Appliquer une défense en profondeur : code, DB, WAF/WAAP, tests, SOC.
- Transformer le sujet en pratiques industrialisées dans le cycle de développement.
Points de vigilance
| Point | Détail | Bon réflexe |
|---|---|---|
| Cause racine | entrée interprétée comme SQL | séparation données / commandes |
| Correction durable | requêtes paramétrées et allow-list | pas de concaténation |
| Réduction impact | moindre privilège DB | segmentation et audit |
| Contrôle continu | tests + logs + WAF + SOC | feedback loop |
Modèle mental
Blind SQL Injection | +--> conception sûre +--> code paramétré +--> DB à privilèges minimaux +--> tests contrôlés +--> détection et réponse
Blind SQL Injection — lecture technique
Une injection SQL apparaît lorsqu’une application mélange une donnée fournie par l’utilisateur avec une instruction SQL au lieu de maintenir une séparation stricte entre le code de la requête et les valeurs. Le problème n’est pas le caractère spécial lui-même : c’est le fait que la base interprète une partie de l’entrée comme de la logique SQL.
| Point | Détail | Bon réflexe |
|---|---|---|
| Symptôme | Concaténation de chaînes, interpolation, requête dynamique non maîtrisée | remplacer par requête paramétrée |
| Racine | Confusion donnée / commande | forcer la séparation dès la couche d’accès DB |
| Amplification | Messages d’erreur trop bavards, compte DB trop privilégié | réduire privilèges et surfaces de fuite |
| Détection | Erreurs SQL, variations de temps, anomalies de volume, patterns suspects | corréler applicatif, DB, WAF et SIEM |
Chaîne logique
Entrée HTTP / API / job | v Validation métier | v Construction requête SQL | +--> mauvais : concaténation/interpolation | +--> bon : SQL fixe + paramètres liés | v DB exécute uniquement l’instruction prévue
Blind SQL Injection — stratégie de test autorisée
Tester SQLi ne consiste pas à lancer des attaques au hasard. Une démarche professionnelle part d’une cartographie des entrées, puis combine revue de code, tests unitaires de repositories, SAST, DAST sur environnement de test, et validation manuelle encadrée.
- Lister les endpoints, paramètres, filtres, headers, payloads JSON, jobs et imports qui atteignent la DB.
- Identifier les requêtes dynamiques, raw SQL, procédures stockées, query builders et générateurs de rapports.
- Vérifier les paramètres liés, allow-lists et bornes numériques.
- Exécuter les tests uniquement sur environnement autorisé avec données non sensibles.
- Créer des tickets correctifs rattachés aux lignes de code et aux routes concernées.
Cas de tests défensifs
| Zone | Objectif de test | Contrôle attendu |
|---|---|---|
| Login | ne pas différencier erreur SQL / auth invalide | réponse générique + logs internes |
| Recherche | requête paramétrée même avec LIKE | concaténer le wildcard côté valeur, pas SQL |
| Tri | champ et direction par allow-list | mapping serveur |
| Export | mêmes protections que l’API interactive | pas de contournement batch |
| Admin | raw SQL encore plus contrôlé | review obligatoire |
Blind SQL Injection — détection et exploitation SOC
| Source | Signal | Action SOC |
|---|---|---|
| HTTP | pics de 4xx/5xx, paramètres atypiques, erreurs applicatives | alerte corrélée route + user + IP |
| WAF/WAAP | règles injection, score anomalie, répétition payloads | distinguer scan, test interne, attaque |
| DB | erreurs syntaxe, requêtes longues, requêtes inhabituelles | lier à request-id si possible |
| IAM | compte applicatif utilisé hors chemin normal | alerter sur privilèges anormaux |
| Données | volumétrie de lecture/export, accès tables sensibles | détection exfiltration |
request_id=abc123 route=/api/search status=500 waf_rule=SQLI_DETECTED db_error=syntax_error user_id=42
- Corréler les événements avec un identifiant de requête.
- Ne pas se limiter au WAF : une SQLi peut être exploitée via API, batch, mobile ou admin interne.
- Créer un playbook : qualifier, isoler, préserver les preuves, corriger la cause, surveiller la récidive.
- Transformer les incidents en tests de régression et règles de revue de code.
Blind SQL Injection — prévention robuste
La défense centrale consiste à écrire une requête dont la structure SQL est connue à l’avance, puis à transmettre les valeurs séparément au driver. Le driver gère l’encodage et la liaison des paramètres sans transformer la valeur en fragment SQL.
# Python / psycopg - correct
cursor.execute(
"SELECT id, email FROM users WHERE email = %s",
(email,)
)
# À éviter
cursor.execute("SELECT id FROM users WHERE email = '" + email + "'")Ce qui complète la paramétrisation
- Allow-list pour les noms de colonnes, tris, directions, types de filtres.
- Moindre privilège : compte applicatif limité aux opérations nécessaires.
- Transactions courtes et requêtes lisibles.
- Logs internes utiles sans fuite de SQL brut côté client.
- Tests automatisés unitaires, intégration, DAST contrôlé, revue SAST.
| Élément | Technique sûre | Règle |
|---|---|---|
| Valeurs | paramètres liés | OK |
| Identifiants SQL | allow-list stricte | jamais depuis input libre |
| ORDER BY | mapping champ public -> colonne interne | direction ASC/DESC whitelistée |
| LIMIT/OFFSET | conversion numérique + bornes | pas de texte libre |
Blind SQL Injection — playbook incident SQLi
1. Qualification
- Identifier route, méthode, paramètre, compte utilisateur, IP, fenêtre temporelle.
- Distinguer test interne, scan externe, exploitation probable.
- Préserver logs WAF, app, reverse proxy, DB et audit.
2. Containment
- Désactiver ou filtrer la route si nécessaire.
- Réduire privilèges du compte applicatif si trop large.
- Ajouter règle WAF temporaire ciblée sans masquer le correctif code.
3. Éradication
- Corriger concaténation/raw SQL.
- Ajouter tests de régression.
- Revoir endpoints similaires.
- Déployer avec rollback possible.
| Sujet | À documenter | Livrable |
|---|---|---|
| Preuves | logs horodatés, payloads, réponses, erreurs DB, traces | chaîne de conservation |
| Données | tables lues/modifiées, exports, comptes affectés | analyse d’impact |
| Communication | juridique, DPO, RSSI, métiers, client si nécessaire | message factuel |
| Post-mortem | racine, délai détection, tests manquants, ownership | plan d’actions |
Blind SQL Injection — analyse détaillée
Cette section relie le sujet à la chaîne complète de sécurité applicative : conception, développement, test, déploiement, supervision et réponse à incident. SQL Injection reste un bon exemple de vulnérabilité apparemment “ancienne” mais durable, car elle naît d’un défaut fondamental de séparation entre données et instructions.
- Identifier les entrées qui atteignent la base.
- Séparer valeurs et structure SQL.
- Limiter les privilèges côté base.
- Ajouter tests et contrôles CI/CD.
- Superviser les signaux applicatifs, WAF et DB.
| Point | Détail | Bon réflexe |
|---|---|---|
| Conception | réduire SQL dynamique | patterns repository sûrs |
| Développement | paramètres liés | revue de code systématique |
| Tests | SAST/DAST/lab | preuve corrigée |
| Production | observabilité + WAF | détection rapide |
Blind SQL Injection — gouvernance et industrialisation
- Définir une politique officielle : requêtes paramétrées obligatoires, raw SQL justifié et revu.
- Ajouter des règles de revue : concaténation SQL interdite, tri/colonnes par allow-list.
- Inscrire SQLi dans le threat modeling des features : recherche, reporting, filtres avancés, exports.
- Créer un module de formation développeur avec exemples du stack réel de l’entreprise.
- Mesurer les progrès : dette raw SQL, couverture tests, incidents, temps de correction.
Definition of Done SQLi-safe [ ] aucune concaténation de données dans SQL [ ] paramètres liés pour toutes les valeurs [ ] allow-list pour identifiants SQL dynamiques [ ] tests unitaires repository [ ] logs sans fuite de SQL sensible [ ] privilèges DB minimaux
Quand une donnée stockée devient dangereuse plus tard dans un autre contexte SQL.
Objectifs pédagogiques
- Comprendre le mécanisme sans tomber dans la simple liste de payloads.
- Savoir reconnaître les zones à risque dans le code et l’architecture.
- Appliquer une défense en profondeur : code, DB, WAF/WAAP, tests, SOC.
- Transformer le sujet en pratiques industrialisées dans le cycle de développement.
Points de vigilance
| Point | Détail | Bon réflexe |
|---|---|---|
| Cause racine | entrée interprétée comme SQL | séparation données / commandes |
| Correction durable | requêtes paramétrées et allow-list | pas de concaténation |
| Réduction impact | moindre privilège DB | segmentation et audit |
| Contrôle continu | tests + logs + WAF + SOC | feedback loop |
Modèle mental
Second-order SQLi | +--> conception sûre +--> code paramétré +--> DB à privilèges minimaux +--> tests contrôlés +--> détection et réponse
Second-order SQLi — familles de SQL Injection
| Famille | Principe | Défense prioritaire |
|---|---|---|
| In-band / classique | Résultat ou erreur observable dans la réponse HTTP | prioriser correction du code et masquage erreurs |
| Union-based | Tentative de combiner un résultat contrôlé avec la requête originale | paramétrisation + contrôle strict des colonnes exposées |
| Error-based | Exploitation des erreurs DB pour révéler structure ou données | messages génériques + logs internes |
| Blind boolean | Inférence par différence de réponse vrai/faux | tests automatisés autorisés + monitoring anomalies |
| Blind time-based | Inférence par délai volontaire | timeouts, détection latence anormale, requêtes paramétrées |
| Second-order | Charge stockée puis réutilisée plus tard dans une requête vulnérable | paramétriser aussi les données déjà stockées |
| Stored procedure unsafe | Procédure stockée qui concatène dynamiquement | procédures paramétrées sans EXEC dynamique non contrôlé |
| NoSQL-like analog | Même famille conceptuelle avec moteurs non SQL | séparer données et opérateurs |
' OR '1'='1 -- exemple pédagogique de test en lab
UNION SELECT ... -- à comprendre, pas à utiliser hors environnement autorisé
donnée stockée -> requête ultérieure -> second-order SQLi
Second-order SQLi — prévention robuste
La défense centrale consiste à écrire une requête dont la structure SQL est connue à l’avance, puis à transmettre les valeurs séparément au driver. Le driver gère l’encodage et la liaison des paramètres sans transformer la valeur en fragment SQL.
# Python / psycopg - correct
cursor.execute(
"SELECT id, email FROM users WHERE email = %s",
(email,)
)
# À éviter
cursor.execute("SELECT id FROM users WHERE email = '" + email + "'")Ce qui complète la paramétrisation
- Allow-list pour les noms de colonnes, tris, directions, types de filtres.
- Moindre privilège : compte applicatif limité aux opérations nécessaires.
- Transactions courtes et requêtes lisibles.
- Logs internes utiles sans fuite de SQL brut côté client.
- Tests automatisés unitaires, intégration, DAST contrôlé, revue SAST.
| Élément | Technique sûre | Règle |
|---|---|---|
| Valeurs | paramètres liés | OK |
| Identifiants SQL | allow-list stricte | jamais depuis input libre |
| ORDER BY | mapping champ public -> colonne interne | direction ASC/DESC whitelistée |
| LIMIT/OFFSET | conversion numérique + bornes | pas de texte libre |
Second-order SQLi — stratégie de test autorisée
Tester SQLi ne consiste pas à lancer des attaques au hasard. Une démarche professionnelle part d’une cartographie des entrées, puis combine revue de code, tests unitaires de repositories, SAST, DAST sur environnement de test, et validation manuelle encadrée.
- Lister les endpoints, paramètres, filtres, headers, payloads JSON, jobs et imports qui atteignent la DB.
- Identifier les requêtes dynamiques, raw SQL, procédures stockées, query builders et générateurs de rapports.
- Vérifier les paramètres liés, allow-lists et bornes numériques.
- Exécuter les tests uniquement sur environnement autorisé avec données non sensibles.
- Créer des tickets correctifs rattachés aux lignes de code et aux routes concernées.
Cas de tests défensifs
| Zone | Objectif de test | Contrôle attendu |
|---|---|---|
| Login | ne pas différencier erreur SQL / auth invalide | réponse générique + logs internes |
| Recherche | requête paramétrée même avec LIKE | concaténer le wildcard côté valeur, pas SQL |
| Tri | champ et direction par allow-list | mapping serveur |
| Export | mêmes protections que l’API interactive | pas de contournement batch |
| Admin | raw SQL encore plus contrôlé | review obligatoire |
Second-order SQLi — exemples de code sécurisé
Django ORM
# Bon : ORM filtre les valeurs
user = User.objects.filter(email=email).first()
# Raw SQL : paramètres obligatoires
User.objects.raw(
"SELECT * FROM app_user WHERE email = %s",
[email]
)Node.js / pg
const result = await client.query( 'SELECT id, email FROM users WHERE email = $1', [email] );
Java / JDBC
PreparedStatement ps = conn.prepareStatement( "SELECT id,email FROM users WHERE email = ?" ); ps.setString(1, email); ResultSet rs = ps.executeQuery();
PHP / PDO
$stmt = $pdo->prepare( 'SELECT id,email FROM users WHERE email = :email' ); $stmt->execute(['email' => $email]);
.NET
using var cmd = new SqlCommand(
"SELECT Id, Email FROM Users WHERE Email = @email", conn);
cmd.Parameters.AddWithValue("@email", email);Go / database/sql
row := db.QueryRowContext(ctx, "SELECT id,email FROM users WHERE email = ?", email, )
Second-order SQLi — détection et exploitation SOC
| Source | Signal | Action SOC |
|---|---|---|
| HTTP | pics de 4xx/5xx, paramètres atypiques, erreurs applicatives | alerte corrélée route + user + IP |
| WAF/WAAP | règles injection, score anomalie, répétition payloads | distinguer scan, test interne, attaque |
| DB | erreurs syntaxe, requêtes longues, requêtes inhabituelles | lier à request-id si possible |
| IAM | compte applicatif utilisé hors chemin normal | alerter sur privilèges anormaux |
| Données | volumétrie de lecture/export, accès tables sensibles | détection exfiltration |
request_id=abc123 route=/api/search status=500 waf_rule=SQLI_DETECTED db_error=syntax_error user_id=42
- Corréler les événements avec un identifiant de requête.
- Ne pas se limiter au WAF : une SQLi peut être exploitée via API, batch, mobile ou admin interne.
- Créer un playbook : qualifier, isoler, préserver les preuves, corriger la cause, surveiller la récidive.
- Transformer les incidents en tests de régression et règles de revue de code.
Second-order SQLi — playbook incident SQLi
1. Qualification
- Identifier route, méthode, paramètre, compte utilisateur, IP, fenêtre temporelle.
- Distinguer test interne, scan externe, exploitation probable.
- Préserver logs WAF, app, reverse proxy, DB et audit.
2. Containment
- Désactiver ou filtrer la route si nécessaire.
- Réduire privilèges du compte applicatif si trop large.
- Ajouter règle WAF temporaire ciblée sans masquer le correctif code.
3. Éradication
- Corriger concaténation/raw SQL.
- Ajouter tests de régression.
- Revoir endpoints similaires.
- Déployer avec rollback possible.
| Sujet | À documenter | Livrable |
|---|---|---|
| Preuves | logs horodatés, payloads, réponses, erreurs DB, traces | chaîne de conservation |
| Données | tables lues/modifiées, exports, comptes affectés | analyse d’impact |
| Communication | juridique, DPO, RSSI, métiers, client si nécessaire | message factuel |
| Post-mortem | racine, délai détection, tests manquants, ownership | plan d’actions |
Second-order SQLi — gouvernance et industrialisation
- Définir une politique officielle : requêtes paramétrées obligatoires, raw SQL justifié et revu.
- Ajouter des règles de revue : concaténation SQL interdite, tri/colonnes par allow-list.
- Inscrire SQLi dans le threat modeling des features : recherche, reporting, filtres avancés, exports.
- Créer un module de formation développeur avec exemples du stack réel de l’entreprise.
- Mesurer les progrès : dette raw SQL, couverture tests, incidents, temps de correction.
Definition of Done SQLi-safe [ ] aucune concaténation de données dans SQL [ ] paramètres liés pour toutes les valeurs [ ] allow-list pour identifiants SQL dynamiques [ ] tests unitaires repository [ ] logs sans fuite de SQL sensible [ ] privilèges DB minimaux
Paramètres GET/POST, JSON, headers, cookies, GraphQL, search, exports, jobs et imports.
Objectifs pédagogiques
- Comprendre le mécanisme sans tomber dans la simple liste de payloads.
- Savoir reconnaître les zones à risque dans le code et l’architecture.
- Appliquer une défense en profondeur : code, DB, WAF/WAAP, tests, SOC.
- Transformer le sujet en pratiques industrialisées dans le cycle de développement.
Points de vigilance
| Point | Détail | Bon réflexe |
|---|---|---|
| Cause racine | entrée interprétée comme SQL | séparation données / commandes |
| Correction durable | requêtes paramétrées et allow-list | pas de concaténation |
| Réduction impact | moindre privilège DB | segmentation et audit |
| Contrôle continu | tests + logs + WAF + SOC | feedback loop |
Modèle mental
Surfaces d’entrée | +--> conception sûre +--> code paramétré +--> DB à privilèges minimaux +--> tests contrôlés +--> détection et réponse
Surfaces d’entrée — stratégie de test autorisée
Tester SQLi ne consiste pas à lancer des attaques au hasard. Une démarche professionnelle part d’une cartographie des entrées, puis combine revue de code, tests unitaires de repositories, SAST, DAST sur environnement de test, et validation manuelle encadrée.
- Lister les endpoints, paramètres, filtres, headers, payloads JSON, jobs et imports qui atteignent la DB.
- Identifier les requêtes dynamiques, raw SQL, procédures stockées, query builders et générateurs de rapports.
- Vérifier les paramètres liés, allow-lists et bornes numériques.
- Exécuter les tests uniquement sur environnement autorisé avec données non sensibles.
- Créer des tickets correctifs rattachés aux lignes de code et aux routes concernées.
Cas de tests défensifs
| Zone | Objectif de test | Contrôle attendu |
|---|---|---|
| Login | ne pas différencier erreur SQL / auth invalide | réponse générique + logs internes |
| Recherche | requête paramétrée même avec LIKE | concaténer le wildcard côté valeur, pas SQL |
| Tri | champ et direction par allow-list | mapping serveur |
| Export | mêmes protections que l’API interactive | pas de contournement batch |
| Admin | raw SQL encore plus contrôlé | review obligatoire |
Surfaces d’entrée — prévention robuste
La défense centrale consiste à écrire une requête dont la structure SQL est connue à l’avance, puis à transmettre les valeurs séparément au driver. Le driver gère l’encodage et la liaison des paramètres sans transformer la valeur en fragment SQL.
# Python / psycopg - correct
cursor.execute(
"SELECT id, email FROM users WHERE email = %s",
(email,)
)
# À éviter
cursor.execute("SELECT id FROM users WHERE email = '" + email + "'")Ce qui complète la paramétrisation
- Allow-list pour les noms de colonnes, tris, directions, types de filtres.
- Moindre privilège : compte applicatif limité aux opérations nécessaires.
- Transactions courtes et requêtes lisibles.
- Logs internes utiles sans fuite de SQL brut côté client.
- Tests automatisés unitaires, intégration, DAST contrôlé, revue SAST.
| Élément | Technique sûre | Règle |
|---|---|---|
| Valeurs | paramètres liés | OK |
| Identifiants SQL | allow-list stricte | jamais depuis input libre |
| ORDER BY | mapping champ public -> colonne interne | direction ASC/DESC whitelistée |
| LIMIT/OFFSET | conversion numérique + bornes | pas de texte libre |
Surfaces d’entrée — détection et exploitation SOC
| Source | Signal | Action SOC |
|---|---|---|
| HTTP | pics de 4xx/5xx, paramètres atypiques, erreurs applicatives | alerte corrélée route + user + IP |
| WAF/WAAP | règles injection, score anomalie, répétition payloads | distinguer scan, test interne, attaque |
| DB | erreurs syntaxe, requêtes longues, requêtes inhabituelles | lier à request-id si possible |
| IAM | compte applicatif utilisé hors chemin normal | alerter sur privilèges anormaux |
| Données | volumétrie de lecture/export, accès tables sensibles | détection exfiltration |
request_id=abc123 route=/api/search status=500 waf_rule=SQLI_DETECTED db_error=syntax_error user_id=42
- Corréler les événements avec un identifiant de requête.
- Ne pas se limiter au WAF : une SQLi peut être exploitée via API, batch, mobile ou admin interne.
- Créer un playbook : qualifier, isoler, préserver les preuves, corriger la cause, surveiller la récidive.
- Transformer les incidents en tests de régression et règles de revue de code.
Surfaces d’entrée — playbook incident SQLi
1. Qualification
- Identifier route, méthode, paramètre, compte utilisateur, IP, fenêtre temporelle.
- Distinguer test interne, scan externe, exploitation probable.
- Préserver logs WAF, app, reverse proxy, DB et audit.
2. Containment
- Désactiver ou filtrer la route si nécessaire.
- Réduire privilèges du compte applicatif si trop large.
- Ajouter règle WAF temporaire ciblée sans masquer le correctif code.
3. Éradication
- Corriger concaténation/raw SQL.
- Ajouter tests de régression.
- Revoir endpoints similaires.
- Déployer avec rollback possible.
| Sujet | À documenter | Livrable |
|---|---|---|
| Preuves | logs horodatés, payloads, réponses, erreurs DB, traces | chaîne de conservation |
| Données | tables lues/modifiées, exports, comptes affectés | analyse d’impact |
| Communication | juridique, DPO, RSSI, métiers, client si nécessaire | message factuel |
| Post-mortem | racine, délai détection, tests manquants, ownership | plan d’actions |
Surfaces d’entrée — gouvernance et industrialisation
- Définir une politique officielle : requêtes paramétrées obligatoires, raw SQL justifié et revu.
- Ajouter des règles de revue : concaténation SQL interdite, tri/colonnes par allow-list.
- Inscrire SQLi dans le threat modeling des features : recherche, reporting, filtres avancés, exports.
- Créer un module de formation développeur avec exemples du stack réel de l’entreprise.
- Mesurer les progrès : dette raw SQL, couverture tests, incidents, temps de correction.
Definition of Done SQLi-safe [ ] aucune concaténation de données dans SQL [ ] paramètres liés pour toutes les valeurs [ ] allow-list pour identifiants SQL dynamiques [ ] tests unitaires repository [ ] logs sans fuite de SQL sensible [ ] privilèges DB minimaux
Surfaces d’entrée — analyse détaillée
Cette section relie le sujet à la chaîne complète de sécurité applicative : conception, développement, test, déploiement, supervision et réponse à incident. SQL Injection reste un bon exemple de vulnérabilité apparemment “ancienne” mais durable, car elle naît d’un défaut fondamental de séparation entre données et instructions.
- Identifier les entrées qui atteignent la base.
- Séparer valeurs et structure SQL.
- Limiter les privilèges côté base.
- Ajouter tests et contrôles CI/CD.
- Superviser les signaux applicatifs, WAF et DB.
| Point | Détail | Bon réflexe |
|---|---|---|
| Conception | réduire SQL dynamique | patterns repository sûrs |
| Développement | paramètres liés | revue de code systématique |
| Tests | SAST/DAST/lab | preuve corrigée |
| Production | observabilité + WAF | détection rapide |
Surfaces d’entrée — exemples de code sécurisé
Django ORM
# Bon : ORM filtre les valeurs
user = User.objects.filter(email=email).first()
# Raw SQL : paramètres obligatoires
User.objects.raw(
"SELECT * FROM app_user WHERE email = %s",
[email]
)Node.js / pg
const result = await client.query( 'SELECT id, email FROM users WHERE email = $1', [email] );
Java / JDBC
PreparedStatement ps = conn.prepareStatement( "SELECT id,email FROM users WHERE email = ?" ); ps.setString(1, email); ResultSet rs = ps.executeQuery();
PHP / PDO
$stmt = $pdo->prepare( 'SELECT id,email FROM users WHERE email = :email' ); $stmt->execute(['email' => $email]);
.NET
using var cmd = new SqlCommand(
"SELECT Id, Email FROM Users WHERE Email = @email", conn);
cmd.Parameters.AddWithValue("@email", email);Go / database/sql
row := db.QueryRowContext(ctx, "SELECT id,email FROM users WHERE email = ?", email, )
Lecture, modification, suppression, contournement d’authentification, pivot, fuite RGPD, crise réputationnelle.
Objectifs pédagogiques
- Comprendre le mécanisme sans tomber dans la simple liste de payloads.
- Savoir reconnaître les zones à risque dans le code et l’architecture.
- Appliquer une défense en profondeur : code, DB, WAF/WAAP, tests, SOC.
- Transformer le sujet en pratiques industrialisées dans le cycle de développement.
Points de vigilance
| Point | Détail | Bon réflexe |
|---|---|---|
| Cause racine | entrée interprétée comme SQL | séparation données / commandes |
| Correction durable | requêtes paramétrées et allow-list | pas de concaténation |
| Réduction impact | moindre privilège DB | segmentation et audit |
| Contrôle continu | tests + logs + WAF + SOC | feedback loop |
Modèle mental
Impacts métier | +--> conception sûre +--> code paramétré +--> DB à privilèges minimaux +--> tests contrôlés +--> détection et réponse
Impacts métier — détection et exploitation SOC
| Source | Signal | Action SOC |
|---|---|---|
| HTTP | pics de 4xx/5xx, paramètres atypiques, erreurs applicatives | alerte corrélée route + user + IP |
| WAF/WAAP | règles injection, score anomalie, répétition payloads | distinguer scan, test interne, attaque |
| DB | erreurs syntaxe, requêtes longues, requêtes inhabituelles | lier à request-id si possible |
| IAM | compte applicatif utilisé hors chemin normal | alerter sur privilèges anormaux |
| Données | volumétrie de lecture/export, accès tables sensibles | détection exfiltration |
request_id=abc123 route=/api/search status=500 waf_rule=SQLI_DETECTED db_error=syntax_error user_id=42
- Corréler les événements avec un identifiant de requête.
- Ne pas se limiter au WAF : une SQLi peut être exploitée via API, batch, mobile ou admin interne.
- Créer un playbook : qualifier, isoler, préserver les preuves, corriger la cause, surveiller la récidive.
- Transformer les incidents en tests de régression et règles de revue de code.
Impacts métier — playbook incident SQLi
1. Qualification
- Identifier route, méthode, paramètre, compte utilisateur, IP, fenêtre temporelle.
- Distinguer test interne, scan externe, exploitation probable.
- Préserver logs WAF, app, reverse proxy, DB et audit.
2. Containment
- Désactiver ou filtrer la route si nécessaire.
- Réduire privilèges du compte applicatif si trop large.
- Ajouter règle WAF temporaire ciblée sans masquer le correctif code.
3. Éradication
- Corriger concaténation/raw SQL.
- Ajouter tests de régression.
- Revoir endpoints similaires.
- Déployer avec rollback possible.
| Sujet | À documenter | Livrable |
|---|---|---|
| Preuves | logs horodatés, payloads, réponses, erreurs DB, traces | chaîne de conservation |
| Données | tables lues/modifiées, exports, comptes affectés | analyse d’impact |
| Communication | juridique, DPO, RSSI, métiers, client si nécessaire | message factuel |
| Post-mortem | racine, délai détection, tests manquants, ownership | plan d’actions |
Impacts métier — gouvernance et industrialisation
- Définir une politique officielle : requêtes paramétrées obligatoires, raw SQL justifié et revu.
- Ajouter des règles de revue : concaténation SQL interdite, tri/colonnes par allow-list.
- Inscrire SQLi dans le threat modeling des features : recherche, reporting, filtres avancés, exports.
- Créer un module de formation développeur avec exemples du stack réel de l’entreprise.
- Mesurer les progrès : dette raw SQL, couverture tests, incidents, temps de correction.
Definition of Done SQLi-safe [ ] aucune concaténation de données dans SQL [ ] paramètres liés pour toutes les valeurs [ ] allow-list pour identifiants SQL dynamiques [ ] tests unitaires repository [ ] logs sans fuite de SQL sensible [ ] privilèges DB minimaux
Impacts métier — stratégie de test autorisée
Tester SQLi ne consiste pas à lancer des attaques au hasard. Une démarche professionnelle part d’une cartographie des entrées, puis combine revue de code, tests unitaires de repositories, SAST, DAST sur environnement de test, et validation manuelle encadrée.
- Lister les endpoints, paramètres, filtres, headers, payloads JSON, jobs et imports qui atteignent la DB.
- Identifier les requêtes dynamiques, raw SQL, procédures stockées, query builders et générateurs de rapports.
- Vérifier les paramètres liés, allow-lists et bornes numériques.
- Exécuter les tests uniquement sur environnement autorisé avec données non sensibles.
- Créer des tickets correctifs rattachés aux lignes de code et aux routes concernées.
Cas de tests défensifs
| Zone | Objectif de test | Contrôle attendu |
|---|---|---|
| Login | ne pas différencier erreur SQL / auth invalide | réponse générique + logs internes |
| Recherche | requête paramétrée même avec LIKE | concaténer le wildcard côté valeur, pas SQL |
| Tri | champ et direction par allow-list | mapping serveur |
| Export | mêmes protections que l’API interactive | pas de contournement batch |
| Admin | raw SQL encore plus contrôlé | review obligatoire |
Impacts métier — prévention robuste
La défense centrale consiste à écrire une requête dont la structure SQL est connue à l’avance, puis à transmettre les valeurs séparément au driver. Le driver gère l’encodage et la liaison des paramètres sans transformer la valeur en fragment SQL.
# Python / psycopg - correct
cursor.execute(
"SELECT id, email FROM users WHERE email = %s",
(email,)
)
# À éviter
cursor.execute("SELECT id FROM users WHERE email = '" + email + "'")Ce qui complète la paramétrisation
- Allow-list pour les noms de colonnes, tris, directions, types de filtres.
- Moindre privilège : compte applicatif limité aux opérations nécessaires.
- Transactions courtes et requêtes lisibles.
- Logs internes utiles sans fuite de SQL brut côté client.
- Tests automatisés unitaires, intégration, DAST contrôlé, revue SAST.
| Élément | Technique sûre | Règle |
|---|---|---|
| Valeurs | paramètres liés | OK |
| Identifiants SQL | allow-list stricte | jamais depuis input libre |
| ORDER BY | mapping champ public -> colonne interne | direction ASC/DESC whitelistée |
| LIMIT/OFFSET | conversion numérique + bornes | pas de texte libre |
Impacts métier — analyse détaillée
Cette section relie le sujet à la chaîne complète de sécurité applicative : conception, développement, test, déploiement, supervision et réponse à incident. SQL Injection reste un bon exemple de vulnérabilité apparemment “ancienne” mais durable, car elle naît d’un défaut fondamental de séparation entre données et instructions.
- Identifier les entrées qui atteignent la base.
- Séparer valeurs et structure SQL.
- Limiter les privilèges côté base.
- Ajouter tests et contrôles CI/CD.
- Superviser les signaux applicatifs, WAF et DB.
| Point | Détail | Bon réflexe |
|---|---|---|
| Conception | réduire SQL dynamique | patterns repository sûrs |
| Développement | paramètres liés | revue de code systématique |
| Tests | SAST/DAST/lab | preuve corrigée |
| Production | observabilité + WAF | détection rapide |
Impacts métier — familles de SQL Injection
| Famille | Principe | Défense prioritaire |
|---|---|---|
| In-band / classique | Résultat ou erreur observable dans la réponse HTTP | prioriser correction du code et masquage erreurs |
| Union-based | Tentative de combiner un résultat contrôlé avec la requête originale | paramétrisation + contrôle strict des colonnes exposées |
| Error-based | Exploitation des erreurs DB pour révéler structure ou données | messages génériques + logs internes |
| Blind boolean | Inférence par différence de réponse vrai/faux | tests automatisés autorisés + monitoring anomalies |
| Blind time-based | Inférence par délai volontaire | timeouts, détection latence anormale, requêtes paramétrées |
| Second-order | Charge stockée puis réutilisée plus tard dans une requête vulnérable | paramétriser aussi les données déjà stockées |
| Stored procedure unsafe | Procédure stockée qui concatène dynamiquement | procédures paramétrées sans EXEC dynamique non contrôlé |
| NoSQL-like analog | Même famille conceptuelle avec moteurs non SQL | séparer données et opérateurs |
' OR '1'='1 -- exemple pédagogique de test en lab
UNION SELECT ... -- à comprendre, pas à utiliser hors environnement autorisé
donnée stockée -> requête ultérieure -> second-order SQLi
Top 10, WSTG, Cheat Sheets, ASVS : comment les utiliser concrètement.
Objectifs pédagogiques
- Comprendre le mécanisme sans tomber dans la simple liste de payloads.
- Savoir reconnaître les zones à risque dans le code et l’architecture.
- Appliquer une défense en profondeur : code, DB, WAF/WAAP, tests, SOC.
- Transformer le sujet en pratiques industrialisées dans le cycle de développement.
Points de vigilance
| Point | Détail | Bon réflexe |
|---|---|---|
| Cause racine | entrée interprétée comme SQL | séparation données / commandes |
| Correction durable | requêtes paramétrées et allow-list | pas de concaténation |
| Réduction impact | moindre privilège DB | segmentation et audit |
| Contrôle continu | tests + logs + WAF + SOC | feedback loop |
Modèle mental
OWASP & référentiels | +--> conception sûre +--> code paramétré +--> DB à privilèges minimaux +--> tests contrôlés +--> détection et réponse
OWASP & référentiels — stratégie de test autorisée
Tester SQLi ne consiste pas à lancer des attaques au hasard. Une démarche professionnelle part d’une cartographie des entrées, puis combine revue de code, tests unitaires de repositories, SAST, DAST sur environnement de test, et validation manuelle encadrée.
- Lister les endpoints, paramètres, filtres, headers, payloads JSON, jobs et imports qui atteignent la DB.
- Identifier les requêtes dynamiques, raw SQL, procédures stockées, query builders et générateurs de rapports.
- Vérifier les paramètres liés, allow-lists et bornes numériques.
- Exécuter les tests uniquement sur environnement autorisé avec données non sensibles.
- Créer des tickets correctifs rattachés aux lignes de code et aux routes concernées.
Cas de tests défensifs
| Zone | Objectif de test | Contrôle attendu |
|---|---|---|
| Login | ne pas différencier erreur SQL / auth invalide | réponse générique + logs internes |
| Recherche | requête paramétrée même avec LIKE | concaténer le wildcard côté valeur, pas SQL |
| Tri | champ et direction par allow-list | mapping serveur |
| Export | mêmes protections que l’API interactive | pas de contournement batch |
| Admin | raw SQL encore plus contrôlé | review obligatoire |
OWASP & référentiels — prévention robuste
La défense centrale consiste à écrire une requête dont la structure SQL est connue à l’avance, puis à transmettre les valeurs séparément au driver. Le driver gère l’encodage et la liaison des paramètres sans transformer la valeur en fragment SQL.
# Python / psycopg - correct
cursor.execute(
"SELECT id, email FROM users WHERE email = %s",
(email,)
)
# À éviter
cursor.execute("SELECT id FROM users WHERE email = '" + email + "'")Ce qui complète la paramétrisation
- Allow-list pour les noms de colonnes, tris, directions, types de filtres.
- Moindre privilège : compte applicatif limité aux opérations nécessaires.
- Transactions courtes et requêtes lisibles.
- Logs internes utiles sans fuite de SQL brut côté client.
- Tests automatisés unitaires, intégration, DAST contrôlé, revue SAST.
| Élément | Technique sûre | Règle |
|---|---|---|
| Valeurs | paramètres liés | OK |
| Identifiants SQL | allow-list stricte | jamais depuis input libre |
| ORDER BY | mapping champ public -> colonne interne | direction ASC/DESC whitelistée |
| LIMIT/OFFSET | conversion numérique + bornes | pas de texte libre |
OWASP & référentiels — gouvernance et industrialisation
- Définir une politique officielle : requêtes paramétrées obligatoires, raw SQL justifié et revu.
- Ajouter des règles de revue : concaténation SQL interdite, tri/colonnes par allow-list.
- Inscrire SQLi dans le threat modeling des features : recherche, reporting, filtres avancés, exports.
- Créer un module de formation développeur avec exemples du stack réel de l’entreprise.
- Mesurer les progrès : dette raw SQL, couverture tests, incidents, temps de correction.
Definition of Done SQLi-safe [ ] aucune concaténation de données dans SQL [ ] paramètres liés pour toutes les valeurs [ ] allow-list pour identifiants SQL dynamiques [ ] tests unitaires repository [ ] logs sans fuite de SQL sensible [ ] privilèges DB minimaux
OWASP & référentiels — lecture technique
Une injection SQL apparaît lorsqu’une application mélange une donnée fournie par l’utilisateur avec une instruction SQL au lieu de maintenir une séparation stricte entre le code de la requête et les valeurs. Le problème n’est pas le caractère spécial lui-même : c’est le fait que la base interprète une partie de l’entrée comme de la logique SQL.
| Point | Détail | Bon réflexe |
|---|---|---|
| Symptôme | Concaténation de chaînes, interpolation, requête dynamique non maîtrisée | remplacer par requête paramétrée |
| Racine | Confusion donnée / commande | forcer la séparation dès la couche d’accès DB |
| Amplification | Messages d’erreur trop bavards, compte DB trop privilégié | réduire privilèges et surfaces de fuite |
| Détection | Erreurs SQL, variations de temps, anomalies de volume, patterns suspects | corréler applicatif, DB, WAF et SIEM |
Chaîne logique
Entrée HTTP / API / job | v Validation métier | v Construction requête SQL | +--> mauvais : concaténation/interpolation | +--> bon : SQL fixe + paramètres liés | v DB exécute uniquement l’instruction prévue
OWASP & référentiels — détection et exploitation SOC
| Source | Signal | Action SOC |
|---|---|---|
| HTTP | pics de 4xx/5xx, paramètres atypiques, erreurs applicatives | alerte corrélée route + user + IP |
| WAF/WAAP | règles injection, score anomalie, répétition payloads | distinguer scan, test interne, attaque |
| DB | erreurs syntaxe, requêtes longues, requêtes inhabituelles | lier à request-id si possible |
| IAM | compte applicatif utilisé hors chemin normal | alerter sur privilèges anormaux |
| Données | volumétrie de lecture/export, accès tables sensibles | détection exfiltration |
request_id=abc123 route=/api/search status=500 waf_rule=SQLI_DETECTED db_error=syntax_error user_id=42
- Corréler les événements avec un identifiant de requête.
- Ne pas se limiter au WAF : une SQLi peut être exploitée via API, batch, mobile ou admin interne.
- Créer un playbook : qualifier, isoler, préserver les preuves, corriger la cause, surveiller la récidive.
- Transformer les incidents en tests de régression et règles de revue de code.
OWASP & référentiels — playbook incident SQLi
1. Qualification
- Identifier route, méthode, paramètre, compte utilisateur, IP, fenêtre temporelle.
- Distinguer test interne, scan externe, exploitation probable.
- Préserver logs WAF, app, reverse proxy, DB et audit.
2. Containment
- Désactiver ou filtrer la route si nécessaire.
- Réduire privilèges du compte applicatif si trop large.
- Ajouter règle WAF temporaire ciblée sans masquer le correctif code.
3. Éradication
- Corriger concaténation/raw SQL.
- Ajouter tests de régression.
- Revoir endpoints similaires.
- Déployer avec rollback possible.
| Sujet | À documenter | Livrable |
|---|---|---|
| Preuves | logs horodatés, payloads, réponses, erreurs DB, traces | chaîne de conservation |
| Données | tables lues/modifiées, exports, comptes affectés | analyse d’impact |
| Communication | juridique, DPO, RSSI, métiers, client si nécessaire | message factuel |
| Post-mortem | racine, délai détection, tests manquants, ownership | plan d’actions |
OWASP & référentiels — exemples de code sécurisé
Django ORM
# Bon : ORM filtre les valeurs
user = User.objects.filter(email=email).first()
# Raw SQL : paramètres obligatoires
User.objects.raw(
"SELECT * FROM app_user WHERE email = %s",
[email]
)Node.js / pg
const result = await client.query( 'SELECT id, email FROM users WHERE email = $1', [email] );
Java / JDBC
PreparedStatement ps = conn.prepareStatement( "SELECT id,email FROM users WHERE email = ?" ); ps.setString(1, email); ResultSet rs = ps.executeQuery();
PHP / PDO
$stmt = $pdo->prepare( 'SELECT id,email FROM users WHERE email = :email' ); $stmt->execute(['email' => $email]);
.NET
using var cmd = new SqlCommand(
"SELECT Id, Email FROM Users WHERE Email = @email", conn);
cmd.Parameters.AddWithValue("@email", email);Go / database/sql
row := db.QueryRowContext(ctx, "SELECT id,email FROM users WHERE email = ?", email, )
Prepared statements, binding, placeholders et séparation stricte SQL/valeurs.
Objectifs pédagogiques
- Comprendre le mécanisme sans tomber dans la simple liste de payloads.
- Savoir reconnaître les zones à risque dans le code et l’architecture.
- Appliquer une défense en profondeur : code, DB, WAF/WAAP, tests, SOC.
- Transformer le sujet en pratiques industrialisées dans le cycle de développement.
Points de vigilance
| Point | Détail | Bon réflexe |
|---|---|---|
| Cause racine | entrée interprétée comme SQL | séparation données / commandes |
| Correction durable | requêtes paramétrées et allow-list | pas de concaténation |
| Réduction impact | moindre privilège DB | segmentation et audit |
| Contrôle continu | tests + logs + WAF + SOC | feedback loop |
Modèle mental
Requêtes paramétrées | +--> conception sûre +--> code paramétré +--> DB à privilèges minimaux +--> tests contrôlés +--> détection et réponse
Requêtes paramétrées — exemples de code sécurisé
Django ORM
# Bon : ORM filtre les valeurs
user = User.objects.filter(email=email).first()
# Raw SQL : paramètres obligatoires
User.objects.raw(
"SELECT * FROM app_user WHERE email = %s",
[email]
)Node.js / pg
const result = await client.query( 'SELECT id, email FROM users WHERE email = $1', [email] );
Java / JDBC
PreparedStatement ps = conn.prepareStatement( "SELECT id,email FROM users WHERE email = ?" ); ps.setString(1, email); ResultSet rs = ps.executeQuery();
PHP / PDO
$stmt = $pdo->prepare( 'SELECT id,email FROM users WHERE email = :email' ); $stmt->execute(['email' => $email]);
.NET
using var cmd = new SqlCommand(
"SELECT Id, Email FROM Users WHERE Email = @email", conn);
cmd.Parameters.AddWithValue("@email", email);Go / database/sql
row := db.QueryRowContext(ctx, "SELECT id,email FROM users WHERE email = ?", email, )
Requêtes paramétrées — lecture technique
Une injection SQL apparaît lorsqu’une application mélange une donnée fournie par l’utilisateur avec une instruction SQL au lieu de maintenir une séparation stricte entre le code de la requête et les valeurs. Le problème n’est pas le caractère spécial lui-même : c’est le fait que la base interprète une partie de l’entrée comme de la logique SQL.
| Point | Détail | Bon réflexe |
|---|---|---|
| Symptôme | Concaténation de chaînes, interpolation, requête dynamique non maîtrisée | remplacer par requête paramétrée |
| Racine | Confusion donnée / commande | forcer la séparation dès la couche d’accès DB |
| Amplification | Messages d’erreur trop bavards, compte DB trop privilégié | réduire privilèges et surfaces de fuite |
| Détection | Erreurs SQL, variations de temps, anomalies de volume, patterns suspects | corréler applicatif, DB, WAF et SIEM |
Chaîne logique
Entrée HTTP / API / job | v Validation métier | v Construction requête SQL | +--> mauvais : concaténation/interpolation | +--> bon : SQL fixe + paramètres liés | v DB exécute uniquement l’instruction prévue
Requêtes paramétrées — stratégie de test autorisée
Tester SQLi ne consiste pas à lancer des attaques au hasard. Une démarche professionnelle part d’une cartographie des entrées, puis combine revue de code, tests unitaires de repositories, SAST, DAST sur environnement de test, et validation manuelle encadrée.
- Lister les endpoints, paramètres, filtres, headers, payloads JSON, jobs et imports qui atteignent la DB.
- Identifier les requêtes dynamiques, raw SQL, procédures stockées, query builders et générateurs de rapports.
- Vérifier les paramètres liés, allow-lists et bornes numériques.
- Exécuter les tests uniquement sur environnement autorisé avec données non sensibles.
- Créer des tickets correctifs rattachés aux lignes de code et aux routes concernées.
Cas de tests défensifs
| Zone | Objectif de test | Contrôle attendu |
|---|---|---|
| Login | ne pas différencier erreur SQL / auth invalide | réponse générique + logs internes |
| Recherche | requête paramétrée même avec LIKE | concaténer le wildcard côté valeur, pas SQL |
| Tri | champ et direction par allow-list | mapping serveur |
| Export | mêmes protections que l’API interactive | pas de contournement batch |
| Admin | raw SQL encore plus contrôlé | review obligatoire |
Requêtes paramétrées — gouvernance et industrialisation
- Définir une politique officielle : requêtes paramétrées obligatoires, raw SQL justifié et revu.
- Ajouter des règles de revue : concaténation SQL interdite, tri/colonnes par allow-list.
- Inscrire SQLi dans le threat modeling des features : recherche, reporting, filtres avancés, exports.
- Créer un module de formation développeur avec exemples du stack réel de l’entreprise.
- Mesurer les progrès : dette raw SQL, couverture tests, incidents, temps de correction.
Definition of Done SQLi-safe [ ] aucune concaténation de données dans SQL [ ] paramètres liés pour toutes les valeurs [ ] allow-list pour identifiants SQL dynamiques [ ] tests unitaires repository [ ] logs sans fuite de SQL sensible [ ] privilèges DB minimaux
Requêtes paramétrées — analyse détaillée
Cette section relie le sujet à la chaîne complète de sécurité applicative : conception, développement, test, déploiement, supervision et réponse à incident. SQL Injection reste un bon exemple de vulnérabilité apparemment “ancienne” mais durable, car elle naît d’un défaut fondamental de séparation entre données et instructions.
- Identifier les entrées qui atteignent la base.
- Séparer valeurs et structure SQL.
- Limiter les privilèges côté base.
- Ajouter tests et contrôles CI/CD.
- Superviser les signaux applicatifs, WAF et DB.
| Point | Détail | Bon réflexe |
|---|---|---|
| Conception | réduire SQL dynamique | patterns repository sûrs |
| Développement | paramètres liés | revue de code systématique |
| Tests | SAST/DAST/lab | preuve corrigée |
| Production | observabilité + WAF | détection rapide |
Requêtes paramétrées — détection et exploitation SOC
| Source | Signal | Action SOC |
|---|---|---|
| HTTP | pics de 4xx/5xx, paramètres atypiques, erreurs applicatives | alerte corrélée route + user + IP |
| WAF/WAAP | règles injection, score anomalie, répétition payloads | distinguer scan, test interne, attaque |
| DB | erreurs syntaxe, requêtes longues, requêtes inhabituelles | lier à request-id si possible |
| IAM | compte applicatif utilisé hors chemin normal | alerter sur privilèges anormaux |
| Données | volumétrie de lecture/export, accès tables sensibles | détection exfiltration |
request_id=abc123 route=/api/search status=500 waf_rule=SQLI_DETECTED db_error=syntax_error user_id=42
- Corréler les événements avec un identifiant de requête.
- Ne pas se limiter au WAF : une SQLi peut être exploitée via API, batch, mobile ou admin interne.
- Créer un playbook : qualifier, isoler, préserver les preuves, corriger la cause, surveiller la récidive.
- Transformer les incidents en tests de régression et règles de revue de code.
Requêtes paramétrées — playbook incident SQLi
1. Qualification
- Identifier route, méthode, paramètre, compte utilisateur, IP, fenêtre temporelle.
- Distinguer test interne, scan externe, exploitation probable.
- Préserver logs WAF, app, reverse proxy, DB et audit.
2. Containment
- Désactiver ou filtrer la route si nécessaire.
- Réduire privilèges du compte applicatif si trop large.
- Ajouter règle WAF temporaire ciblée sans masquer le correctif code.
3. Éradication
- Corriger concaténation/raw SQL.
- Ajouter tests de régression.
- Revoir endpoints similaires.
- Déployer avec rollback possible.
| Sujet | À documenter | Livrable |
|---|---|---|
| Preuves | logs horodatés, payloads, réponses, erreurs DB, traces | chaîne de conservation |
| Données | tables lues/modifiées, exports, comptes affectés | analyse d’impact |
| Communication | juridique, DPO, RSSI, métiers, client si nécessaire | message factuel |
| Post-mortem | racine, délai détection, tests manquants, ownership | plan d’actions |
Comprendre ce que l’ORM protège réellement et où il ne protège plus.
Objectifs pédagogiques
- Comprendre le mécanisme sans tomber dans la simple liste de payloads.
- Savoir reconnaître les zones à risque dans le code et l’architecture.
- Appliquer une défense en profondeur : code, DB, WAF/WAAP, tests, SOC.
- Transformer le sujet en pratiques industrialisées dans le cycle de développement.
Points de vigilance
| Point | Détail | Bon réflexe |
|---|---|---|
| Cause racine | entrée interprétée comme SQL | séparation données / commandes |
| Correction durable | requêtes paramétrées et allow-list | pas de concaténation |
| Réduction impact | moindre privilège DB | segmentation et audit |
| Contrôle continu | tests + logs + WAF + SOC | feedback loop |
Modèle mental
ORM & query builders | +--> conception sûre +--> code paramétré +--> DB à privilèges minimaux +--> tests contrôlés +--> détection et réponse
ORM & query builders — exemples de code sécurisé
Django ORM
# Bon : ORM filtre les valeurs
user = User.objects.filter(email=email).first()
# Raw SQL : paramètres obligatoires
User.objects.raw(
"SELECT * FROM app_user WHERE email = %s",
[email]
)Node.js / pg
const result = await client.query( 'SELECT id, email FROM users WHERE email = $1', [email] );
Java / JDBC
PreparedStatement ps = conn.prepareStatement( "SELECT id,email FROM users WHERE email = ?" ); ps.setString(1, email); ResultSet rs = ps.executeQuery();
PHP / PDO
$stmt = $pdo->prepare( 'SELECT id,email FROM users WHERE email = :email' ); $stmt->execute(['email' => $email]);
.NET
using var cmd = new SqlCommand(
"SELECT Id, Email FROM Users WHERE Email = @email", conn);
cmd.Parameters.AddWithValue("@email", email);Go / database/sql
row := db.QueryRowContext(ctx, "SELECT id,email FROM users WHERE email = ?", email, )
ORM & query builders — lecture technique
Une injection SQL apparaît lorsqu’une application mélange une donnée fournie par l’utilisateur avec une instruction SQL au lieu de maintenir une séparation stricte entre le code de la requête et les valeurs. Le problème n’est pas le caractère spécial lui-même : c’est le fait que la base interprète une partie de l’entrée comme de la logique SQL.
| Point | Détail | Bon réflexe |
|---|---|---|
| Symptôme | Concaténation de chaînes, interpolation, requête dynamique non maîtrisée | remplacer par requête paramétrée |
| Racine | Confusion donnée / commande | forcer la séparation dès la couche d’accès DB |
| Amplification | Messages d’erreur trop bavards, compte DB trop privilégié | réduire privilèges et surfaces de fuite |
| Détection | Erreurs SQL, variations de temps, anomalies de volume, patterns suspects | corréler applicatif, DB, WAF et SIEM |
Chaîne logique
Entrée HTTP / API / job | v Validation métier | v Construction requête SQL | +--> mauvais : concaténation/interpolation | +--> bon : SQL fixe + paramètres liés | v DB exécute uniquement l’instruction prévue
ORM & query builders — stratégie de test autorisée
Tester SQLi ne consiste pas à lancer des attaques au hasard. Une démarche professionnelle part d’une cartographie des entrées, puis combine revue de code, tests unitaires de repositories, SAST, DAST sur environnement de test, et validation manuelle encadrée.
- Lister les endpoints, paramètres, filtres, headers, payloads JSON, jobs et imports qui atteignent la DB.
- Identifier les requêtes dynamiques, raw SQL, procédures stockées, query builders et générateurs de rapports.
- Vérifier les paramètres liés, allow-lists et bornes numériques.
- Exécuter les tests uniquement sur environnement autorisé avec données non sensibles.
- Créer des tickets correctifs rattachés aux lignes de code et aux routes concernées.
Cas de tests défensifs
| Zone | Objectif de test | Contrôle attendu |
|---|---|---|
| Login | ne pas différencier erreur SQL / auth invalide | réponse générique + logs internes |
| Recherche | requête paramétrée même avec LIKE | concaténer le wildcard côté valeur, pas SQL |
| Tri | champ et direction par allow-list | mapping serveur |
| Export | mêmes protections que l’API interactive | pas de contournement batch |
| Admin | raw SQL encore plus contrôlé | review obligatoire |
ORM & query builders — analyse détaillée
Cette section relie le sujet à la chaîne complète de sécurité applicative : conception, développement, test, déploiement, supervision et réponse à incident. SQL Injection reste un bon exemple de vulnérabilité apparemment “ancienne” mais durable, car elle naît d’un défaut fondamental de séparation entre données et instructions.
- Identifier les entrées qui atteignent la base.
- Séparer valeurs et structure SQL.
- Limiter les privilèges côté base.
- Ajouter tests et contrôles CI/CD.
- Superviser les signaux applicatifs, WAF et DB.
| Point | Détail | Bon réflexe |
|---|---|---|
| Conception | réduire SQL dynamique | patterns repository sûrs |
| Développement | paramètres liés | revue de code systématique |
| Tests | SAST/DAST/lab | preuve corrigée |
| Production | observabilité + WAF | détection rapide |
ORM & query builders — gouvernance et industrialisation
- Définir une politique officielle : requêtes paramétrées obligatoires, raw SQL justifié et revu.
- Ajouter des règles de revue : concaténation SQL interdite, tri/colonnes par allow-list.
- Inscrire SQLi dans le threat modeling des features : recherche, reporting, filtres avancés, exports.
- Créer un module de formation développeur avec exemples du stack réel de l’entreprise.
- Mesurer les progrès : dette raw SQL, couverture tests, incidents, temps de correction.
Definition of Done SQLi-safe [ ] aucune concaténation de données dans SQL [ ] paramètres liés pour toutes les valeurs [ ] allow-list pour identifiants SQL dynamiques [ ] tests unitaires repository [ ] logs sans fuite de SQL sensible [ ] privilèges DB minimaux
ORM & query builders — détection et exploitation SOC
| Source | Signal | Action SOC |
|---|---|---|
| HTTP | pics de 4xx/5xx, paramètres atypiques, erreurs applicatives | alerte corrélée route + user + IP |
| WAF/WAAP | règles injection, score anomalie, répétition payloads | distinguer scan, test interne, attaque |
| DB | erreurs syntaxe, requêtes longues, requêtes inhabituelles | lier à request-id si possible |
| IAM | compte applicatif utilisé hors chemin normal | alerter sur privilèges anormaux |
| Données | volumétrie de lecture/export, accès tables sensibles | détection exfiltration |
request_id=abc123 route=/api/search status=500 waf_rule=SQLI_DETECTED db_error=syntax_error user_id=42
- Corréler les événements avec un identifiant de requête.
- Ne pas se limiter au WAF : une SQLi peut être exploitée via API, batch, mobile ou admin interne.
- Créer un playbook : qualifier, isoler, préserver les preuves, corriger la cause, surveiller la récidive.
- Transformer les incidents en tests de régression et règles de revue de code.
ORM & query builders — playbook incident SQLi
1. Qualification
- Identifier route, méthode, paramètre, compte utilisateur, IP, fenêtre temporelle.
- Distinguer test interne, scan externe, exploitation probable.
- Préserver logs WAF, app, reverse proxy, DB et audit.
2. Containment
- Désactiver ou filtrer la route si nécessaire.
- Réduire privilèges du compte applicatif si trop large.
- Ajouter règle WAF temporaire ciblée sans masquer le correctif code.
3. Éradication
- Corriger concaténation/raw SQL.
- Ajouter tests de régression.
- Revoir endpoints similaires.
- Déployer avec rollback possible.
| Sujet | À documenter | Livrable |
|---|---|---|
| Preuves | logs horodatés, payloads, réponses, erreurs DB, traces | chaîne de conservation |
| Données | tables lues/modifiées, exports, comptes affectés | analyse d’impact |
| Communication | juridique, DPO, RSSI, métiers, client si nécessaire | message factuel |
| Post-mortem | racine, délai détection, tests manquants, ownership | plan d’actions |
ORDER BY, filtres, colonnes, rapports, exports : allow-list et mapping serveur.
Objectifs pédagogiques
- Comprendre le mécanisme sans tomber dans la simple liste de payloads.
- Savoir reconnaître les zones à risque dans le code et l’architecture.
- Appliquer une défense en profondeur : code, DB, WAF/WAAP, tests, SOC.
- Transformer le sujet en pratiques industrialisées dans le cycle de développement.
Points de vigilance
| Point | Détail | Bon réflexe |
|---|---|---|
| Cause racine | entrée interprétée comme SQL | séparation données / commandes |
| Correction durable | requêtes paramétrées et allow-list | pas de concaténation |
| Réduction impact | moindre privilège DB | segmentation et audit |
| Contrôle continu | tests + logs + WAF + SOC | feedback loop |
Modèle mental
SQL dynamique contrôlé | +--> conception sûre +--> code paramétré +--> DB à privilèges minimaux +--> tests contrôlés +--> détection et réponse
SQL dynamique contrôlé — exemples de code sécurisé
Django ORM
# Bon : ORM filtre les valeurs
user = User.objects.filter(email=email).first()
# Raw SQL : paramètres obligatoires
User.objects.raw(
"SELECT * FROM app_user WHERE email = %s",
[email]
)Node.js / pg
const result = await client.query( 'SELECT id, email FROM users WHERE email = $1', [email] );
Java / JDBC
PreparedStatement ps = conn.prepareStatement( "SELECT id,email FROM users WHERE email = ?" ); ps.setString(1, email); ResultSet rs = ps.executeQuery();
PHP / PDO
$stmt = $pdo->prepare( 'SELECT id,email FROM users WHERE email = :email' ); $stmt->execute(['email' => $email]);
.NET
using var cmd = new SqlCommand(
"SELECT Id, Email FROM Users WHERE Email = @email", conn);
cmd.Parameters.AddWithValue("@email", email);Go / database/sql
row := db.QueryRowContext(ctx, "SELECT id,email FROM users WHERE email = ?", email, )
SQL dynamique contrôlé — stratégie de test autorisée
Tester SQLi ne consiste pas à lancer des attaques au hasard. Une démarche professionnelle part d’une cartographie des entrées, puis combine revue de code, tests unitaires de repositories, SAST, DAST sur environnement de test, et validation manuelle encadrée.
- Lister les endpoints, paramètres, filtres, headers, payloads JSON, jobs et imports qui atteignent la DB.
- Identifier les requêtes dynamiques, raw SQL, procédures stockées, query builders et générateurs de rapports.
- Vérifier les paramètres liés, allow-lists et bornes numériques.
- Exécuter les tests uniquement sur environnement autorisé avec données non sensibles.
- Créer des tickets correctifs rattachés aux lignes de code et aux routes concernées.
Cas de tests défensifs
| Zone | Objectif de test | Contrôle attendu |
|---|---|---|
| Login | ne pas différencier erreur SQL / auth invalide | réponse générique + logs internes |
| Recherche | requête paramétrée même avec LIKE | concaténer le wildcard côté valeur, pas SQL |
| Tri | champ et direction par allow-list | mapping serveur |
| Export | mêmes protections que l’API interactive | pas de contournement batch |
| Admin | raw SQL encore plus contrôlé | review obligatoire |
SQL dynamique contrôlé — lecture technique
Une injection SQL apparaît lorsqu’une application mélange une donnée fournie par l’utilisateur avec une instruction SQL au lieu de maintenir une séparation stricte entre le code de la requête et les valeurs. Le problème n’est pas le caractère spécial lui-même : c’est le fait que la base interprète une partie de l’entrée comme de la logique SQL.
| Point | Détail | Bon réflexe |
|---|---|---|
| Symptôme | Concaténation de chaînes, interpolation, requête dynamique non maîtrisée | remplacer par requête paramétrée |
| Racine | Confusion donnée / commande | forcer la séparation dès la couche d’accès DB |
| Amplification | Messages d’erreur trop bavards, compte DB trop privilégié | réduire privilèges et surfaces de fuite |
| Détection | Erreurs SQL, variations de temps, anomalies de volume, patterns suspects | corréler applicatif, DB, WAF et SIEM |
Chaîne logique
Entrée HTTP / API / job | v Validation métier | v Construction requête SQL | +--> mauvais : concaténation/interpolation | +--> bon : SQL fixe + paramètres liés | v DB exécute uniquement l’instruction prévue
SQL dynamique contrôlé — analyse détaillée
Cette section relie le sujet à la chaîne complète de sécurité applicative : conception, développement, test, déploiement, supervision et réponse à incident. SQL Injection reste un bon exemple de vulnérabilité apparemment “ancienne” mais durable, car elle naît d’un défaut fondamental de séparation entre données et instructions.
- Identifier les entrées qui atteignent la base.
- Séparer valeurs et structure SQL.
- Limiter les privilèges côté base.
- Ajouter tests et contrôles CI/CD.
- Superviser les signaux applicatifs, WAF et DB.
| Point | Détail | Bon réflexe |
|---|---|---|
| Conception | réduire SQL dynamique | patterns repository sûrs |
| Développement | paramètres liés | revue de code systématique |
| Tests | SAST/DAST/lab | preuve corrigée |
| Production | observabilité + WAF | détection rapide |
SQL dynamique contrôlé — gouvernance et industrialisation
- Définir une politique officielle : requêtes paramétrées obligatoires, raw SQL justifié et revu.
- Ajouter des règles de revue : concaténation SQL interdite, tri/colonnes par allow-list.
- Inscrire SQLi dans le threat modeling des features : recherche, reporting, filtres avancés, exports.
- Créer un module de formation développeur avec exemples du stack réel de l’entreprise.
- Mesurer les progrès : dette raw SQL, couverture tests, incidents, temps de correction.
Definition of Done SQLi-safe [ ] aucune concaténation de données dans SQL [ ] paramètres liés pour toutes les valeurs [ ] allow-list pour identifiants SQL dynamiques [ ] tests unitaires repository [ ] logs sans fuite de SQL sensible [ ] privilèges DB minimaux
SQL dynamique contrôlé — détection et exploitation SOC
| Source | Signal | Action SOC |
|---|---|---|
| HTTP | pics de 4xx/5xx, paramètres atypiques, erreurs applicatives | alerte corrélée route + user + IP |
| WAF/WAAP | règles injection, score anomalie, répétition payloads | distinguer scan, test interne, attaque |
| DB | erreurs syntaxe, requêtes longues, requêtes inhabituelles | lier à request-id si possible |
| IAM | compte applicatif utilisé hors chemin normal | alerter sur privilèges anormaux |
| Données | volumétrie de lecture/export, accès tables sensibles | détection exfiltration |
request_id=abc123 route=/api/search status=500 waf_rule=SQLI_DETECTED db_error=syntax_error user_id=42
- Corréler les événements avec un identifiant de requête.
- Ne pas se limiter au WAF : une SQLi peut être exploitée via API, batch, mobile ou admin interne.
- Créer un playbook : qualifier, isoler, préserver les preuves, corriger la cause, surveiller la récidive.
- Transformer les incidents en tests de régression et règles de revue de code.
SQL dynamique contrôlé — playbook incident SQLi
1. Qualification
- Identifier route, méthode, paramètre, compte utilisateur, IP, fenêtre temporelle.
- Distinguer test interne, scan externe, exploitation probable.
- Préserver logs WAF, app, reverse proxy, DB et audit.
2. Containment
- Désactiver ou filtrer la route si nécessaire.
- Réduire privilèges du compte applicatif si trop large.
- Ajouter règle WAF temporaire ciblée sans masquer le correctif code.
3. Éradication
- Corriger concaténation/raw SQL.
- Ajouter tests de régression.
- Revoir endpoints similaires.
- Déployer avec rollback possible.
| Sujet | À documenter | Livrable |
|---|---|---|
| Preuves | logs horodatés, payloads, réponses, erreurs DB, traces | chaîne de conservation |
| Données | tables lues/modifiées, exports, comptes affectés | analyse d’impact |
| Communication | juridique, DPO, RSSI, métiers, client si nécessaire | message factuel |
| Post-mortem | racine, délai détection, tests manquants, ownership | plan d’actions |
Éviter les fuites tout en gardant des logs utiles pour le diagnostic.
Objectifs pédagogiques
- Comprendre le mécanisme sans tomber dans la simple liste de payloads.
- Savoir reconnaître les zones à risque dans le code et l’architecture.
- Appliquer une défense en profondeur : code, DB, WAF/WAAP, tests, SOC.
- Transformer le sujet en pratiques industrialisées dans le cycle de développement.
Points de vigilance
| Point | Détail | Bon réflexe |
|---|---|---|
| Cause racine | entrée interprétée comme SQL | séparation données / commandes |
| Correction durable | requêtes paramétrées et allow-list | pas de concaténation |
| Réduction impact | moindre privilège DB | segmentation et audit |
| Contrôle continu | tests + logs + WAF + SOC | feedback loop |
Modèle mental
Erreurs, logs et messages | +--> conception sûre +--> code paramétré +--> DB à privilèges minimaux +--> tests contrôlés +--> détection et réponse
Erreurs, logs et messages — playbook incident SQLi
1. Qualification
- Identifier route, méthode, paramètre, compte utilisateur, IP, fenêtre temporelle.
- Distinguer test interne, scan externe, exploitation probable.
- Préserver logs WAF, app, reverse proxy, DB et audit.
2. Containment
- Désactiver ou filtrer la route si nécessaire.
- Réduire privilèges du compte applicatif si trop large.
- Ajouter règle WAF temporaire ciblée sans masquer le correctif code.
3. Éradication
- Corriger concaténation/raw SQL.
- Ajouter tests de régression.
- Revoir endpoints similaires.
- Déployer avec rollback possible.
| Sujet | À documenter | Livrable |
|---|---|---|
| Preuves | logs horodatés, payloads, réponses, erreurs DB, traces | chaîne de conservation |
| Données | tables lues/modifiées, exports, comptes affectés | analyse d’impact |
| Communication | juridique, DPO, RSSI, métiers, client si nécessaire | message factuel |
| Post-mortem | racine, délai détection, tests manquants, ownership | plan d’actions |
Erreurs, logs et messages — prévention robuste
La défense centrale consiste à écrire une requête dont la structure SQL est connue à l’avance, puis à transmettre les valeurs séparément au driver. Le driver gère l’encodage et la liaison des paramètres sans transformer la valeur en fragment SQL.
# Python / psycopg - correct
cursor.execute(
"SELECT id, email FROM users WHERE email = %s",
(email,)
)
# À éviter
cursor.execute("SELECT id FROM users WHERE email = '" + email + "'")Ce qui complète la paramétrisation
- Allow-list pour les noms de colonnes, tris, directions, types de filtres.
- Moindre privilège : compte applicatif limité aux opérations nécessaires.
- Transactions courtes et requêtes lisibles.
- Logs internes utiles sans fuite de SQL brut côté client.
- Tests automatisés unitaires, intégration, DAST contrôlé, revue SAST.
| Élément | Technique sûre | Règle |
|---|---|---|
| Valeurs | paramètres liés | OK |
| Identifiants SQL | allow-list stricte | jamais depuis input libre |
| ORDER BY | mapping champ public -> colonne interne | direction ASC/DESC whitelistée |
| LIMIT/OFFSET | conversion numérique + bornes | pas de texte libre |
Erreurs, logs et messages — stratégie de test autorisée
Tester SQLi ne consiste pas à lancer des attaques au hasard. Une démarche professionnelle part d’une cartographie des entrées, puis combine revue de code, tests unitaires de repositories, SAST, DAST sur environnement de test, et validation manuelle encadrée.
- Lister les endpoints, paramètres, filtres, headers, payloads JSON, jobs et imports qui atteignent la DB.
- Identifier les requêtes dynamiques, raw SQL, procédures stockées, query builders et générateurs de rapports.
- Vérifier les paramètres liés, allow-lists et bornes numériques.
- Exécuter les tests uniquement sur environnement autorisé avec données non sensibles.
- Créer des tickets correctifs rattachés aux lignes de code et aux routes concernées.
Cas de tests défensifs
| Zone | Objectif de test | Contrôle attendu |
|---|---|---|
| Login | ne pas différencier erreur SQL / auth invalide | réponse générique + logs internes |
| Recherche | requête paramétrée même avec LIKE | concaténer le wildcard côté valeur, pas SQL |
| Tri | champ et direction par allow-list | mapping serveur |
| Export | mêmes protections que l’API interactive | pas de contournement batch |
| Admin | raw SQL encore plus contrôlé | review obligatoire |
Erreurs, logs et messages — lecture technique
Une injection SQL apparaît lorsqu’une application mélange une donnée fournie par l’utilisateur avec une instruction SQL au lieu de maintenir une séparation stricte entre le code de la requête et les valeurs. Le problème n’est pas le caractère spécial lui-même : c’est le fait que la base interprète une partie de l’entrée comme de la logique SQL.
| Point | Détail | Bon réflexe |
|---|---|---|
| Symptôme | Concaténation de chaînes, interpolation, requête dynamique non maîtrisée | remplacer par requête paramétrée |
| Racine | Confusion donnée / commande | forcer la séparation dès la couche d’accès DB |
| Amplification | Messages d’erreur trop bavards, compte DB trop privilégié | réduire privilèges et surfaces de fuite |
| Détection | Erreurs SQL, variations de temps, anomalies de volume, patterns suspects | corréler applicatif, DB, WAF et SIEM |
Chaîne logique
Entrée HTTP / API / job | v Validation métier | v Construction requête SQL | +--> mauvais : concaténation/interpolation | +--> bon : SQL fixe + paramètres liés | v DB exécute uniquement l’instruction prévue
Erreurs, logs et messages — gouvernance et industrialisation
- Définir une politique officielle : requêtes paramétrées obligatoires, raw SQL justifié et revu.
- Ajouter des règles de revue : concaténation SQL interdite, tri/colonnes par allow-list.
- Inscrire SQLi dans le threat modeling des features : recherche, reporting, filtres avancés, exports.
- Créer un module de formation développeur avec exemples du stack réel de l’entreprise.
- Mesurer les progrès : dette raw SQL, couverture tests, incidents, temps de correction.
Definition of Done SQLi-safe [ ] aucune concaténation de données dans SQL [ ] paramètres liés pour toutes les valeurs [ ] allow-list pour identifiants SQL dynamiques [ ] tests unitaires repository [ ] logs sans fuite de SQL sensible [ ] privilèges DB minimaux
Erreurs, logs et messages — analyse détaillée
Cette section relie le sujet à la chaîne complète de sécurité applicative : conception, développement, test, déploiement, supervision et réponse à incident. SQL Injection reste un bon exemple de vulnérabilité apparemment “ancienne” mais durable, car elle naît d’un défaut fondamental de séparation entre données et instructions.
- Identifier les entrées qui atteignent la base.
- Séparer valeurs et structure SQL.
- Limiter les privilèges côté base.
- Ajouter tests et contrôles CI/CD.
- Superviser les signaux applicatifs, WAF et DB.
| Point | Détail | Bon réflexe |
|---|---|---|
| Conception | réduire SQL dynamique | patterns repository sûrs |
| Développement | paramètres liés | revue de code systématique |
| Tests | SAST/DAST/lab | preuve corrigée |
| Production | observabilité + WAF | détection rapide |
Erreurs, logs et messages — exemples de code sécurisé
Django ORM
# Bon : ORM filtre les valeurs
user = User.objects.filter(email=email).first()
# Raw SQL : paramètres obligatoires
User.objects.raw(
"SELECT * FROM app_user WHERE email = %s",
[email]
)Node.js / pg
const result = await client.query( 'SELECT id, email FROM users WHERE email = $1', [email] );
Java / JDBC
PreparedStatement ps = conn.prepareStatement( "SELECT id,email FROM users WHERE email = ?" ); ps.setString(1, email); ResultSet rs = ps.executeQuery();
PHP / PDO
$stmt = $pdo->prepare( 'SELECT id,email FROM users WHERE email = :email' ); $stmt->execute(['email' => $email]);
.NET
using var cmd = new SqlCommand(
"SELECT Id, Email FROM Users WHERE Email = @email", conn);
cmd.Parameters.AddWithValue("@email", email);Go / database/sql
row := db.QueryRowContext(ctx, "SELECT id,email FROM users WHERE email = ?", email, )
Limiter l’impact : comptes, rôles, vues, procédures, segmentation et secrets.
Objectifs pédagogiques
- Comprendre le mécanisme sans tomber dans la simple liste de payloads.
- Savoir reconnaître les zones à risque dans le code et l’architecture.
- Appliquer une défense en profondeur : code, DB, WAF/WAAP, tests, SOC.
- Transformer le sujet en pratiques industrialisées dans le cycle de développement.
Points de vigilance
| Point | Détail | Bon réflexe |
|---|---|---|
| Cause racine | entrée interprétée comme SQL | séparation données / commandes |
| Correction durable | requêtes paramétrées et allow-list | pas de concaténation |
| Réduction impact | moindre privilège DB | segmentation et audit |
| Contrôle continu | tests + logs + WAF + SOC | feedback loop |
Modèle mental
Moindre privilège DB | +--> conception sûre +--> code paramétré +--> DB à privilèges minimaux +--> tests contrôlés +--> détection et réponse
Moindre privilège DB — playbook incident SQLi
1. Qualification
- Identifier route, méthode, paramètre, compte utilisateur, IP, fenêtre temporelle.
- Distinguer test interne, scan externe, exploitation probable.
- Préserver logs WAF, app, reverse proxy, DB et audit.
2. Containment
- Désactiver ou filtrer la route si nécessaire.
- Réduire privilèges du compte applicatif si trop large.
- Ajouter règle WAF temporaire ciblée sans masquer le correctif code.
3. Éradication
- Corriger concaténation/raw SQL.
- Ajouter tests de régression.
- Revoir endpoints similaires.
- Déployer avec rollback possible.
| Sujet | À documenter | Livrable |
|---|---|---|
| Preuves | logs horodatés, payloads, réponses, erreurs DB, traces | chaîne de conservation |
| Données | tables lues/modifiées, exports, comptes affectés | analyse d’impact |
| Communication | juridique, DPO, RSSI, métiers, client si nécessaire | message factuel |
| Post-mortem | racine, délai détection, tests manquants, ownership | plan d’actions |
Moindre privilège DB — détection et exploitation SOC
| Source | Signal | Action SOC |
|---|---|---|
| HTTP | pics de 4xx/5xx, paramètres atypiques, erreurs applicatives | alerte corrélée route + user + IP |
| WAF/WAAP | règles injection, score anomalie, répétition payloads | distinguer scan, test interne, attaque |
| DB | erreurs syntaxe, requêtes longues, requêtes inhabituelles | lier à request-id si possible |
| IAM | compte applicatif utilisé hors chemin normal | alerter sur privilèges anormaux |
| Données | volumétrie de lecture/export, accès tables sensibles | détection exfiltration |
request_id=abc123 route=/api/search status=500 waf_rule=SQLI_DETECTED db_error=syntax_error user_id=42
- Corréler les événements avec un identifiant de requête.
- Ne pas se limiter au WAF : une SQLi peut être exploitée via API, batch, mobile ou admin interne.
- Créer un playbook : qualifier, isoler, préserver les preuves, corriger la cause, surveiller la récidive.
- Transformer les incidents en tests de régression et règles de revue de code.
Moindre privilège DB — gouvernance et industrialisation
- Définir une politique officielle : requêtes paramétrées obligatoires, raw SQL justifié et revu.
- Ajouter des règles de revue : concaténation SQL interdite, tri/colonnes par allow-list.
- Inscrire SQLi dans le threat modeling des features : recherche, reporting, filtres avancés, exports.
- Créer un module de formation développeur avec exemples du stack réel de l’entreprise.
- Mesurer les progrès : dette raw SQL, couverture tests, incidents, temps de correction.
Definition of Done SQLi-safe [ ] aucune concaténation de données dans SQL [ ] paramètres liés pour toutes les valeurs [ ] allow-list pour identifiants SQL dynamiques [ ] tests unitaires repository [ ] logs sans fuite de SQL sensible [ ] privilèges DB minimaux
Moindre privilège DB — stratégie de test autorisée
Tester SQLi ne consiste pas à lancer des attaques au hasard. Une démarche professionnelle part d’une cartographie des entrées, puis combine revue de code, tests unitaires de repositories, SAST, DAST sur environnement de test, et validation manuelle encadrée.
- Lister les endpoints, paramètres, filtres, headers, payloads JSON, jobs et imports qui atteignent la DB.
- Identifier les requêtes dynamiques, raw SQL, procédures stockées, query builders et générateurs de rapports.
- Vérifier les paramètres liés, allow-lists et bornes numériques.
- Exécuter les tests uniquement sur environnement autorisé avec données non sensibles.
- Créer des tickets correctifs rattachés aux lignes de code et aux routes concernées.
Cas de tests défensifs
| Zone | Objectif de test | Contrôle attendu |
|---|---|---|
| Login | ne pas différencier erreur SQL / auth invalide | réponse générique + logs internes |
| Recherche | requête paramétrée même avec LIKE | concaténer le wildcard côté valeur, pas SQL |
| Tri | champ et direction par allow-list | mapping serveur |
| Export | mêmes protections que l’API interactive | pas de contournement batch |
| Admin | raw SQL encore plus contrôlé | review obligatoire |
Moindre privilège DB — lecture technique
Une injection SQL apparaît lorsqu’une application mélange une donnée fournie par l’utilisateur avec une instruction SQL au lieu de maintenir une séparation stricte entre le code de la requête et les valeurs. Le problème n’est pas le caractère spécial lui-même : c’est le fait que la base interprète une partie de l’entrée comme de la logique SQL.
| Point | Détail | Bon réflexe |
|---|---|---|
| Symptôme | Concaténation de chaînes, interpolation, requête dynamique non maîtrisée | remplacer par requête paramétrée |
| Racine | Confusion donnée / commande | forcer la séparation dès la couche d’accès DB |
| Amplification | Messages d’erreur trop bavards, compte DB trop privilégié | réduire privilèges et surfaces de fuite |
| Détection | Erreurs SQL, variations de temps, anomalies de volume, patterns suspects | corréler applicatif, DB, WAF et SIEM |
Chaîne logique
Entrée HTTP / API / job | v Validation métier | v Construction requête SQL | +--> mauvais : concaténation/interpolation | +--> bon : SQL fixe + paramètres liés | v DB exécute uniquement l’instruction prévue
Moindre privilège DB — analyse détaillée
Cette section relie le sujet à la chaîne complète de sécurité applicative : conception, développement, test, déploiement, supervision et réponse à incident. SQL Injection reste un bon exemple de vulnérabilité apparemment “ancienne” mais durable, car elle naît d’un défaut fondamental de séparation entre données et instructions.
- Identifier les entrées qui atteignent la base.
- Séparer valeurs et structure SQL.
- Limiter les privilèges côté base.
- Ajouter tests et contrôles CI/CD.
- Superviser les signaux applicatifs, WAF et DB.
| Point | Détail | Bon réflexe |
|---|---|---|
| Conception | réduire SQL dynamique | patterns repository sûrs |
| Développement | paramètres liés | revue de code systématique |
| Tests | SAST/DAST/lab | preuve corrigée |
| Production | observabilité + WAF | détection rapide |
Moindre privilège DB — exemples de code sécurisé
Django ORM
# Bon : ORM filtre les valeurs
user = User.objects.filter(email=email).first()
# Raw SQL : paramètres obligatoires
User.objects.raw(
"SELECT * FROM app_user WHERE email = %s",
[email]
)Node.js / pg
const result = await client.query( 'SELECT id, email FROM users WHERE email = $1', [email] );
Java / JDBC
PreparedStatement ps = conn.prepareStatement( "SELECT id,email FROM users WHERE email = ?" ); ps.setString(1, email); ResultSet rs = ps.executeQuery();
PHP / PDO
$stmt = $pdo->prepare( 'SELECT id,email FROM users WHERE email = :email' ); $stmt->execute(['email' => $email]);
.NET
using var cmd = new SqlCommand(
"SELECT Id, Email FROM Users WHERE Email = @email", conn);
cmd.Parameters.AddWithValue("@email", email);Go / database/sql
row := db.QueryRowContext(ctx, "SELECT id,email FROM users WHERE email = ?", email, )
Méthodologie WSTG : revue, SAST, DAST, tests manuels autorisés et preuve de correction.
Objectifs pédagogiques
- Comprendre le mécanisme sans tomber dans la simple liste de payloads.
- Savoir reconnaître les zones à risque dans le code et l’architecture.
- Appliquer une défense en profondeur : code, DB, WAF/WAAP, tests, SOC.
- Transformer le sujet en pratiques industrialisées dans le cycle de développement.
Points de vigilance
| Point | Détail | Bon réflexe |
|---|---|---|
| Cause racine | entrée interprétée comme SQL | séparation données / commandes |
| Correction durable | requêtes paramétrées et allow-list | pas de concaténation |
| Réduction impact | moindre privilège DB | segmentation et audit |
| Contrôle continu | tests + logs + WAF + SOC | feedback loop |
Modèle mental
Tests SQLi contrôlés | +--> conception sûre +--> code paramétré +--> DB à privilèges minimaux +--> tests contrôlés +--> détection et réponse
Tests SQLi contrôlés — lecture technique
Une injection SQL apparaît lorsqu’une application mélange une donnée fournie par l’utilisateur avec une instruction SQL au lieu de maintenir une séparation stricte entre le code de la requête et les valeurs. Le problème n’est pas le caractère spécial lui-même : c’est le fait que la base interprète une partie de l’entrée comme de la logique SQL.
| Point | Détail | Bon réflexe |
|---|---|---|
| Symptôme | Concaténation de chaînes, interpolation, requête dynamique non maîtrisée | remplacer par requête paramétrée |
| Racine | Confusion donnée / commande | forcer la séparation dès la couche d’accès DB |
| Amplification | Messages d’erreur trop bavards, compte DB trop privilégié | réduire privilèges et surfaces de fuite |
| Détection | Erreurs SQL, variations de temps, anomalies de volume, patterns suspects | corréler applicatif, DB, WAF et SIEM |
Chaîne logique
Entrée HTTP / API / job | v Validation métier | v Construction requête SQL | +--> mauvais : concaténation/interpolation | +--> bon : SQL fixe + paramètres liés | v DB exécute uniquement l’instruction prévue
Tests SQLi contrôlés — prévention robuste
La défense centrale consiste à écrire une requête dont la structure SQL est connue à l’avance, puis à transmettre les valeurs séparément au driver. Le driver gère l’encodage et la liaison des paramètres sans transformer la valeur en fragment SQL.
# Python / psycopg - correct
cursor.execute(
"SELECT id, email FROM users WHERE email = %s",
(email,)
)
# À éviter
cursor.execute("SELECT id FROM users WHERE email = '" + email + "'")Ce qui complète la paramétrisation
- Allow-list pour les noms de colonnes, tris, directions, types de filtres.
- Moindre privilège : compte applicatif limité aux opérations nécessaires.
- Transactions courtes et requêtes lisibles.
- Logs internes utiles sans fuite de SQL brut côté client.
- Tests automatisés unitaires, intégration, DAST contrôlé, revue SAST.
| Élément | Technique sûre | Règle |
|---|---|---|
| Valeurs | paramètres liés | OK |
| Identifiants SQL | allow-list stricte | jamais depuis input libre |
| ORDER BY | mapping champ public -> colonne interne | direction ASC/DESC whitelistée |
| LIMIT/OFFSET | conversion numérique + bornes | pas de texte libre |
Tests SQLi contrôlés — détection et exploitation SOC
| Source | Signal | Action SOC |
|---|---|---|
| HTTP | pics de 4xx/5xx, paramètres atypiques, erreurs applicatives | alerte corrélée route + user + IP |
| WAF/WAAP | règles injection, score anomalie, répétition payloads | distinguer scan, test interne, attaque |
| DB | erreurs syntaxe, requêtes longues, requêtes inhabituelles | lier à request-id si possible |
| IAM | compte applicatif utilisé hors chemin normal | alerter sur privilèges anormaux |
| Données | volumétrie de lecture/export, accès tables sensibles | détection exfiltration |
request_id=abc123 route=/api/search status=500 waf_rule=SQLI_DETECTED db_error=syntax_error user_id=42
- Corréler les événements avec un identifiant de requête.
- Ne pas se limiter au WAF : une SQLi peut être exploitée via API, batch, mobile ou admin interne.
- Créer un playbook : qualifier, isoler, préserver les preuves, corriger la cause, surveiller la récidive.
- Transformer les incidents en tests de régression et règles de revue de code.
Tests SQLi contrôlés — playbook incident SQLi
1. Qualification
- Identifier route, méthode, paramètre, compte utilisateur, IP, fenêtre temporelle.
- Distinguer test interne, scan externe, exploitation probable.
- Préserver logs WAF, app, reverse proxy, DB et audit.
2. Containment
- Désactiver ou filtrer la route si nécessaire.
- Réduire privilèges du compte applicatif si trop large.
- Ajouter règle WAF temporaire ciblée sans masquer le correctif code.
3. Éradication
- Corriger concaténation/raw SQL.
- Ajouter tests de régression.
- Revoir endpoints similaires.
- Déployer avec rollback possible.
| Sujet | À documenter | Livrable |
|---|---|---|
| Preuves | logs horodatés, payloads, réponses, erreurs DB, traces | chaîne de conservation |
| Données | tables lues/modifiées, exports, comptes affectés | analyse d’impact |
| Communication | juridique, DPO, RSSI, métiers, client si nécessaire | message factuel |
| Post-mortem | racine, délai détection, tests manquants, ownership | plan d’actions |
Tests SQLi contrôlés — gouvernance et industrialisation
- Définir une politique officielle : requêtes paramétrées obligatoires, raw SQL justifié et revu.
- Ajouter des règles de revue : concaténation SQL interdite, tri/colonnes par allow-list.
- Inscrire SQLi dans le threat modeling des features : recherche, reporting, filtres avancés, exports.
- Créer un module de formation développeur avec exemples du stack réel de l’entreprise.
- Mesurer les progrès : dette raw SQL, couverture tests, incidents, temps de correction.
Definition of Done SQLi-safe [ ] aucune concaténation de données dans SQL [ ] paramètres liés pour toutes les valeurs [ ] allow-list pour identifiants SQL dynamiques [ ] tests unitaires repository [ ] logs sans fuite de SQL sensible [ ] privilèges DB minimaux
Tests SQLi contrôlés — analyse détaillée
Cette section relie le sujet à la chaîne complète de sécurité applicative : conception, développement, test, déploiement, supervision et réponse à incident. SQL Injection reste un bon exemple de vulnérabilité apparemment “ancienne” mais durable, car elle naît d’un défaut fondamental de séparation entre données et instructions.
- Identifier les entrées qui atteignent la base.
- Séparer valeurs et structure SQL.
- Limiter les privilèges côté base.
- Ajouter tests et contrôles CI/CD.
- Superviser les signaux applicatifs, WAF et DB.
| Point | Détail | Bon réflexe |
|---|---|---|
| Conception | réduire SQL dynamique | patterns repository sûrs |
| Développement | paramètres liés | revue de code systématique |
| Tests | SAST/DAST/lab | preuve corrigée |
| Production | observabilité + WAF | détection rapide |
Tests SQLi contrôlés — exemples de code sécurisé
Django ORM
# Bon : ORM filtre les valeurs
user = User.objects.filter(email=email).first()
# Raw SQL : paramètres obligatoires
User.objects.raw(
"SELECT * FROM app_user WHERE email = %s",
[email]
)Node.js / pg
const result = await client.query( 'SELECT id, email FROM users WHERE email = $1', [email] );
Java / JDBC
PreparedStatement ps = conn.prepareStatement( "SELECT id,email FROM users WHERE email = ?" ); ps.setString(1, email); ResultSet rs = ps.executeQuery();
PHP / PDO
$stmt = $pdo->prepare( 'SELECT id,email FROM users WHERE email = :email' ); $stmt->execute(['email' => $email]);
.NET
using var cmd = new SqlCommand(
"SELECT Id, Email FROM Users WHERE Email = @email", conn);
cmd.Parameters.AddWithValue("@email", email);Go / database/sql
row := db.QueryRowContext(ctx, "SELECT id,email FROM users WHERE email = ?", email, )
Intégrer SQLi dans la Definition of Done, pipelines et qualité de code.
Objectifs pédagogiques
- Comprendre le mécanisme sans tomber dans la simple liste de payloads.
- Savoir reconnaître les zones à risque dans le code et l’architecture.
- Appliquer une défense en profondeur : code, DB, WAF/WAAP, tests, SOC.
- Transformer le sujet en pratiques industrialisées dans le cycle de développement.
Points de vigilance
| Point | Détail | Bon réflexe |
|---|---|---|
| Cause racine | entrée interprétée comme SQL | séparation données / commandes |
| Correction durable | requêtes paramétrées et allow-list | pas de concaténation |
| Réduction impact | moindre privilège DB | segmentation et audit |
| Contrôle continu | tests + logs + WAF + SOC | feedback loop |
Modèle mental
CI/CD & DevSecOps | +--> conception sûre +--> code paramétré +--> DB à privilèges minimaux +--> tests contrôlés +--> détection et réponse
CI/CD & DevSecOps — stratégie de test autorisée
Tester SQLi ne consiste pas à lancer des attaques au hasard. Une démarche professionnelle part d’une cartographie des entrées, puis combine revue de code, tests unitaires de repositories, SAST, DAST sur environnement de test, et validation manuelle encadrée.
- Lister les endpoints, paramètres, filtres, headers, payloads JSON, jobs et imports qui atteignent la DB.
- Identifier les requêtes dynamiques, raw SQL, procédures stockées, query builders et générateurs de rapports.
- Vérifier les paramètres liés, allow-lists et bornes numériques.
- Exécuter les tests uniquement sur environnement autorisé avec données non sensibles.
- Créer des tickets correctifs rattachés aux lignes de code et aux routes concernées.
Cas de tests défensifs
| Zone | Objectif de test | Contrôle attendu |
|---|---|---|
| Login | ne pas différencier erreur SQL / auth invalide | réponse générique + logs internes |
| Recherche | requête paramétrée même avec LIKE | concaténer le wildcard côté valeur, pas SQL |
| Tri | champ et direction par allow-list | mapping serveur |
| Export | mêmes protections que l’API interactive | pas de contournement batch |
| Admin | raw SQL encore plus contrôlé | review obligatoire |
CI/CD & DevSecOps — prévention robuste
La défense centrale consiste à écrire une requête dont la structure SQL est connue à l’avance, puis à transmettre les valeurs séparément au driver. Le driver gère l’encodage et la liaison des paramètres sans transformer la valeur en fragment SQL.
# Python / psycopg - correct
cursor.execute(
"SELECT id, email FROM users WHERE email = %s",
(email,)
)
# À éviter
cursor.execute("SELECT id FROM users WHERE email = '" + email + "'")Ce qui complète la paramétrisation
- Allow-list pour les noms de colonnes, tris, directions, types de filtres.
- Moindre privilège : compte applicatif limité aux opérations nécessaires.
- Transactions courtes et requêtes lisibles.
- Logs internes utiles sans fuite de SQL brut côté client.
- Tests automatisés unitaires, intégration, DAST contrôlé, revue SAST.
| Élément | Technique sûre | Règle |
|---|---|---|
| Valeurs | paramètres liés | OK |
| Identifiants SQL | allow-list stricte | jamais depuis input libre |
| ORDER BY | mapping champ public -> colonne interne | direction ASC/DESC whitelistée |
| LIMIT/OFFSET | conversion numérique + bornes | pas de texte libre |
CI/CD & DevSecOps — exemples de code sécurisé
Django ORM
# Bon : ORM filtre les valeurs
user = User.objects.filter(email=email).first()
# Raw SQL : paramètres obligatoires
User.objects.raw(
"SELECT * FROM app_user WHERE email = %s",
[email]
)Node.js / pg
const result = await client.query( 'SELECT id, email FROM users WHERE email = $1', [email] );
Java / JDBC
PreparedStatement ps = conn.prepareStatement( "SELECT id,email FROM users WHERE email = ?" ); ps.setString(1, email); ResultSet rs = ps.executeQuery();
PHP / PDO
$stmt = $pdo->prepare( 'SELECT id,email FROM users WHERE email = :email' ); $stmt->execute(['email' => $email]);
.NET
using var cmd = new SqlCommand(
"SELECT Id, Email FROM Users WHERE Email = @email", conn);
cmd.Parameters.AddWithValue("@email", email);Go / database/sql
row := db.QueryRowContext(ctx, "SELECT id,email FROM users WHERE email = ?", email, )
CI/CD & DevSecOps — détection et exploitation SOC
| Source | Signal | Action SOC |
|---|---|---|
| HTTP | pics de 4xx/5xx, paramètres atypiques, erreurs applicatives | alerte corrélée route + user + IP |
| WAF/WAAP | règles injection, score anomalie, répétition payloads | distinguer scan, test interne, attaque |
| DB | erreurs syntaxe, requêtes longues, requêtes inhabituelles | lier à request-id si possible |
| IAM | compte applicatif utilisé hors chemin normal | alerter sur privilèges anormaux |
| Données | volumétrie de lecture/export, accès tables sensibles | détection exfiltration |
request_id=abc123 route=/api/search status=500 waf_rule=SQLI_DETECTED db_error=syntax_error user_id=42
- Corréler les événements avec un identifiant de requête.
- Ne pas se limiter au WAF : une SQLi peut être exploitée via API, batch, mobile ou admin interne.
- Créer un playbook : qualifier, isoler, préserver les preuves, corriger la cause, surveiller la récidive.
- Transformer les incidents en tests de régression et règles de revue de code.
CI/CD & DevSecOps — playbook incident SQLi
1. Qualification
- Identifier route, méthode, paramètre, compte utilisateur, IP, fenêtre temporelle.
- Distinguer test interne, scan externe, exploitation probable.
- Préserver logs WAF, app, reverse proxy, DB et audit.
2. Containment
- Désactiver ou filtrer la route si nécessaire.
- Réduire privilèges du compte applicatif si trop large.
- Ajouter règle WAF temporaire ciblée sans masquer le correctif code.
3. Éradication
- Corriger concaténation/raw SQL.
- Ajouter tests de régression.
- Revoir endpoints similaires.
- Déployer avec rollback possible.
| Sujet | À documenter | Livrable |
|---|---|---|
| Preuves | logs horodatés, payloads, réponses, erreurs DB, traces | chaîne de conservation |
| Données | tables lues/modifiées, exports, comptes affectés | analyse d’impact |
| Communication | juridique, DPO, RSSI, métiers, client si nécessaire | message factuel |
| Post-mortem | racine, délai détection, tests manquants, ownership | plan d’actions |
CI/CD & DevSecOps — lecture technique
Une injection SQL apparaît lorsqu’une application mélange une donnée fournie par l’utilisateur avec une instruction SQL au lieu de maintenir une séparation stricte entre le code de la requête et les valeurs. Le problème n’est pas le caractère spécial lui-même : c’est le fait que la base interprète une partie de l’entrée comme de la logique SQL.
| Point | Détail | Bon réflexe |
|---|---|---|
| Symptôme | Concaténation de chaînes, interpolation, requête dynamique non maîtrisée | remplacer par requête paramétrée |
| Racine | Confusion donnée / commande | forcer la séparation dès la couche d’accès DB |
| Amplification | Messages d’erreur trop bavards, compte DB trop privilégié | réduire privilèges et surfaces de fuite |
| Détection | Erreurs SQL, variations de temps, anomalies de volume, patterns suspects | corréler applicatif, DB, WAF et SIEM |
Chaîne logique
Entrée HTTP / API / job | v Validation métier | v Construction requête SQL | +--> mauvais : concaténation/interpolation | +--> bon : SQL fixe + paramètres liés | v DB exécute uniquement l’instruction prévue
CI/CD & DevSecOps — analyse détaillée
Cette section relie le sujet à la chaîne complète de sécurité applicative : conception, développement, test, déploiement, supervision et réponse à incident. SQL Injection reste un bon exemple de vulnérabilité apparemment “ancienne” mais durable, car elle naît d’un défaut fondamental de séparation entre données et instructions.
- Identifier les entrées qui atteignent la base.
- Séparer valeurs et structure SQL.
- Limiter les privilèges côté base.
- Ajouter tests et contrôles CI/CD.
- Superviser les signaux applicatifs, WAF et DB.
| Point | Détail | Bon réflexe |
|---|---|---|
| Conception | réduire SQL dynamique | patterns repository sûrs |
| Développement | paramètres liés | revue de code systématique |
| Tests | SAST/DAST/lab | preuve corrigée |
| Production | observabilité + WAF | détection rapide |
Détection et blocage complémentaires : règles, scoring, faux positifs, tuning, limites.
Objectifs pédagogiques
- Comprendre le mécanisme sans tomber dans la simple liste de payloads.
- Savoir reconnaître les zones à risque dans le code et l’architecture.
- Appliquer une défense en profondeur : code, DB, WAF/WAAP, tests, SOC.
- Transformer le sujet en pratiques industrialisées dans le cycle de développement.
Points de vigilance
| Point | Détail | Bon réflexe |
|---|---|---|
| Cause racine | entrée interprétée comme SQL | séparation données / commandes |
| Correction durable | requêtes paramétrées et allow-list | pas de concaténation |
| Réduction impact | moindre privilège DB | segmentation et audit |
| Contrôle continu | tests + logs + WAF + SOC | feedback loop |
Modèle mental
WAF / WAAP | +--> conception sûre +--> code paramétré +--> DB à privilèges minimaux +--> tests contrôlés +--> détection et réponse
WAF / WAAP — prévention robuste
La défense centrale consiste à écrire une requête dont la structure SQL est connue à l’avance, puis à transmettre les valeurs séparément au driver. Le driver gère l’encodage et la liaison des paramètres sans transformer la valeur en fragment SQL.
# Python / psycopg - correct
cursor.execute(
"SELECT id, email FROM users WHERE email = %s",
(email,)
)
# À éviter
cursor.execute("SELECT id FROM users WHERE email = '" + email + "'")Ce qui complète la paramétrisation
- Allow-list pour les noms de colonnes, tris, directions, types de filtres.
- Moindre privilège : compte applicatif limité aux opérations nécessaires.
- Transactions courtes et requêtes lisibles.
- Logs internes utiles sans fuite de SQL brut côté client.
- Tests automatisés unitaires, intégration, DAST contrôlé, revue SAST.
| Élément | Technique sûre | Règle |
|---|---|---|
| Valeurs | paramètres liés | OK |
| Identifiants SQL | allow-list stricte | jamais depuis input libre |
| ORDER BY | mapping champ public -> colonne interne | direction ASC/DESC whitelistée |
| LIMIT/OFFSET | conversion numérique + bornes | pas de texte libre |
WAF / WAAP — stratégie de test autorisée
Tester SQLi ne consiste pas à lancer des attaques au hasard. Une démarche professionnelle part d’une cartographie des entrées, puis combine revue de code, tests unitaires de repositories, SAST, DAST sur environnement de test, et validation manuelle encadrée.
- Lister les endpoints, paramètres, filtres, headers, payloads JSON, jobs et imports qui atteignent la DB.
- Identifier les requêtes dynamiques, raw SQL, procédures stockées, query builders et générateurs de rapports.
- Vérifier les paramètres liés, allow-lists et bornes numériques.
- Exécuter les tests uniquement sur environnement autorisé avec données non sensibles.
- Créer des tickets correctifs rattachés aux lignes de code et aux routes concernées.
Cas de tests défensifs
| Zone | Objectif de test | Contrôle attendu |
|---|---|---|
| Login | ne pas différencier erreur SQL / auth invalide | réponse générique + logs internes |
| Recherche | requête paramétrée même avec LIKE | concaténer le wildcard côté valeur, pas SQL |
| Tri | champ et direction par allow-list | mapping serveur |
| Export | mêmes protections que l’API interactive | pas de contournement batch |
| Admin | raw SQL encore plus contrôlé | review obligatoire |
WAF / WAAP — playbook incident SQLi
1. Qualification
- Identifier route, méthode, paramètre, compte utilisateur, IP, fenêtre temporelle.
- Distinguer test interne, scan externe, exploitation probable.
- Préserver logs WAF, app, reverse proxy, DB et audit.
2. Containment
- Désactiver ou filtrer la route si nécessaire.
- Réduire privilèges du compte applicatif si trop large.
- Ajouter règle WAF temporaire ciblée sans masquer le correctif code.
3. Éradication
- Corriger concaténation/raw SQL.
- Ajouter tests de régression.
- Revoir endpoints similaires.
- Déployer avec rollback possible.
| Sujet | À documenter | Livrable |
|---|---|---|
| Preuves | logs horodatés, payloads, réponses, erreurs DB, traces | chaîne de conservation |
| Données | tables lues/modifiées, exports, comptes affectés | analyse d’impact |
| Communication | juridique, DPO, RSSI, métiers, client si nécessaire | message factuel |
| Post-mortem | racine, délai détection, tests manquants, ownership | plan d’actions |
WAF / WAAP — lecture technique
Une injection SQL apparaît lorsqu’une application mélange une donnée fournie par l’utilisateur avec une instruction SQL au lieu de maintenir une séparation stricte entre le code de la requête et les valeurs. Le problème n’est pas le caractère spécial lui-même : c’est le fait que la base interprète une partie de l’entrée comme de la logique SQL.
| Point | Détail | Bon réflexe |
|---|---|---|
| Symptôme | Concaténation de chaînes, interpolation, requête dynamique non maîtrisée | remplacer par requête paramétrée |
| Racine | Confusion donnée / commande | forcer la séparation dès la couche d’accès DB |
| Amplification | Messages d’erreur trop bavards, compte DB trop privilégié | réduire privilèges et surfaces de fuite |
| Détection | Erreurs SQL, variations de temps, anomalies de volume, patterns suspects | corréler applicatif, DB, WAF et SIEM |
Chaîne logique
Entrée HTTP / API / job | v Validation métier | v Construction requête SQL | +--> mauvais : concaténation/interpolation | +--> bon : SQL fixe + paramètres liés | v DB exécute uniquement l’instruction prévue
WAF / WAAP — gouvernance et industrialisation
- Définir une politique officielle : requêtes paramétrées obligatoires, raw SQL justifié et revu.
- Ajouter des règles de revue : concaténation SQL interdite, tri/colonnes par allow-list.
- Inscrire SQLi dans le threat modeling des features : recherche, reporting, filtres avancés, exports.
- Créer un module de formation développeur avec exemples du stack réel de l’entreprise.
- Mesurer les progrès : dette raw SQL, couverture tests, incidents, temps de correction.
Definition of Done SQLi-safe [ ] aucune concaténation de données dans SQL [ ] paramètres liés pour toutes les valeurs [ ] allow-list pour identifiants SQL dynamiques [ ] tests unitaires repository [ ] logs sans fuite de SQL sensible [ ] privilèges DB minimaux
WAF / WAAP — analyse détaillée
Cette section relie le sujet à la chaîne complète de sécurité applicative : conception, développement, test, déploiement, supervision et réponse à incident. SQL Injection reste un bon exemple de vulnérabilité apparemment “ancienne” mais durable, car elle naît d’un défaut fondamental de séparation entre données et instructions.
- Identifier les entrées qui atteignent la base.
- Séparer valeurs et structure SQL.
- Limiter les privilèges côté base.
- Ajouter tests et contrôles CI/CD.
- Superviser les signaux applicatifs, WAF et DB.
| Point | Détail | Bon réflexe |
|---|---|---|
| Conception | réduire SQL dynamique | patterns repository sûrs |
| Développement | paramètres liés | revue de code systématique |
| Tests | SAST/DAST/lab | preuve corrigée |
| Production | observabilité + WAF | détection rapide |
WAF / WAAP — familles de SQL Injection
| Famille | Principe | Défense prioritaire |
|---|---|---|
| In-band / classique | Résultat ou erreur observable dans la réponse HTTP | prioriser correction du code et masquage erreurs |
| Union-based | Tentative de combiner un résultat contrôlé avec la requête originale | paramétrisation + contrôle strict des colonnes exposées |
| Error-based | Exploitation des erreurs DB pour révéler structure ou données | messages génériques + logs internes |
| Blind boolean | Inférence par différence de réponse vrai/faux | tests automatisés autorisés + monitoring anomalies |
| Blind time-based | Inférence par délai volontaire | timeouts, détection latence anormale, requêtes paramétrées |
| Second-order | Charge stockée puis réutilisée plus tard dans une requête vulnérable | paramétriser aussi les données déjà stockées |
| Stored procedure unsafe | Procédure stockée qui concatène dynamiquement | procédures paramétrées sans EXEC dynamique non contrôlé |
| NoSQL-like analog | Même famille conceptuelle avec moteurs non SQL | séparer données et opérateurs |
' OR '1'='1 -- exemple pédagogique de test en lab
UNION SELECT ... -- à comprendre, pas à utiliser hors environnement autorisé
donnée stockée -> requête ultérieure -> second-order SQLi
Corréler WAF, app, DB, IAM et données pour détecter les tentatives et exploitations.
Objectifs pédagogiques
- Comprendre le mécanisme sans tomber dans la simple liste de payloads.
- Savoir reconnaître les zones à risque dans le code et l’architecture.
- Appliquer une défense en profondeur : code, DB, WAF/WAAP, tests, SOC.
- Transformer le sujet en pratiques industrialisées dans le cycle de développement.
Points de vigilance
| Point | Détail | Bon réflexe |
|---|---|---|
| Cause racine | entrée interprétée comme SQL | séparation données / commandes |
| Correction durable | requêtes paramétrées et allow-list | pas de concaténation |
| Réduction impact | moindre privilège DB | segmentation et audit |
| Contrôle continu | tests + logs + WAF + SOC | feedback loop |
Modèle mental
Détection SOC/SIEM | +--> conception sûre +--> code paramétré +--> DB à privilèges minimaux +--> tests contrôlés +--> détection et réponse
Détection SOC/SIEM — playbook incident SQLi
1. Qualification
- Identifier route, méthode, paramètre, compte utilisateur, IP, fenêtre temporelle.
- Distinguer test interne, scan externe, exploitation probable.
- Préserver logs WAF, app, reverse proxy, DB et audit.
2. Containment
- Désactiver ou filtrer la route si nécessaire.
- Réduire privilèges du compte applicatif si trop large.
- Ajouter règle WAF temporaire ciblée sans masquer le correctif code.
3. Éradication
- Corriger concaténation/raw SQL.
- Ajouter tests de régression.
- Revoir endpoints similaires.
- Déployer avec rollback possible.
| Sujet | À documenter | Livrable |
|---|---|---|
| Preuves | logs horodatés, payloads, réponses, erreurs DB, traces | chaîne de conservation |
| Données | tables lues/modifiées, exports, comptes affectés | analyse d’impact |
| Communication | juridique, DPO, RSSI, métiers, client si nécessaire | message factuel |
| Post-mortem | racine, délai détection, tests manquants, ownership | plan d’actions |
Détection SOC/SIEM — stratégie de test autorisée
Tester SQLi ne consiste pas à lancer des attaques au hasard. Une démarche professionnelle part d’une cartographie des entrées, puis combine revue de code, tests unitaires de repositories, SAST, DAST sur environnement de test, et validation manuelle encadrée.
- Lister les endpoints, paramètres, filtres, headers, payloads JSON, jobs et imports qui atteignent la DB.
- Identifier les requêtes dynamiques, raw SQL, procédures stockées, query builders et générateurs de rapports.
- Vérifier les paramètres liés, allow-lists et bornes numériques.
- Exécuter les tests uniquement sur environnement autorisé avec données non sensibles.
- Créer des tickets correctifs rattachés aux lignes de code et aux routes concernées.
Cas de tests défensifs
| Zone | Objectif de test | Contrôle attendu |
|---|---|---|
| Login | ne pas différencier erreur SQL / auth invalide | réponse générique + logs internes |
| Recherche | requête paramétrée même avec LIKE | concaténer le wildcard côté valeur, pas SQL |
| Tri | champ et direction par allow-list | mapping serveur |
| Export | mêmes protections que l’API interactive | pas de contournement batch |
| Admin | raw SQL encore plus contrôlé | review obligatoire |
Détection SOC/SIEM — prévention robuste
La défense centrale consiste à écrire une requête dont la structure SQL est connue à l’avance, puis à transmettre les valeurs séparément au driver. Le driver gère l’encodage et la liaison des paramètres sans transformer la valeur en fragment SQL.
# Python / psycopg - correct
cursor.execute(
"SELECT id, email FROM users WHERE email = %s",
(email,)
)
# À éviter
cursor.execute("SELECT id FROM users WHERE email = '" + email + "'")Ce qui complète la paramétrisation
- Allow-list pour les noms de colonnes, tris, directions, types de filtres.
- Moindre privilège : compte applicatif limité aux opérations nécessaires.
- Transactions courtes et requêtes lisibles.
- Logs internes utiles sans fuite de SQL brut côté client.
- Tests automatisés unitaires, intégration, DAST contrôlé, revue SAST.
| Élément | Technique sûre | Règle |
|---|---|---|
| Valeurs | paramètres liés | OK |
| Identifiants SQL | allow-list stricte | jamais depuis input libre |
| ORDER BY | mapping champ public -> colonne interne | direction ASC/DESC whitelistée |
| LIMIT/OFFSET | conversion numérique + bornes | pas de texte libre |
Détection SOC/SIEM — gouvernance et industrialisation
- Définir une politique officielle : requêtes paramétrées obligatoires, raw SQL justifié et revu.
- Ajouter des règles de revue : concaténation SQL interdite, tri/colonnes par allow-list.
- Inscrire SQLi dans le threat modeling des features : recherche, reporting, filtres avancés, exports.
- Créer un module de formation développeur avec exemples du stack réel de l’entreprise.
- Mesurer les progrès : dette raw SQL, couverture tests, incidents, temps de correction.
Definition of Done SQLi-safe [ ] aucune concaténation de données dans SQL [ ] paramètres liés pour toutes les valeurs [ ] allow-list pour identifiants SQL dynamiques [ ] tests unitaires repository [ ] logs sans fuite de SQL sensible [ ] privilèges DB minimaux
Détection SOC/SIEM — lecture technique
Une injection SQL apparaît lorsqu’une application mélange une donnée fournie par l’utilisateur avec une instruction SQL au lieu de maintenir une séparation stricte entre le code de la requête et les valeurs. Le problème n’est pas le caractère spécial lui-même : c’est le fait que la base interprète une partie de l’entrée comme de la logique SQL.
| Point | Détail | Bon réflexe |
|---|---|---|
| Symptôme | Concaténation de chaînes, interpolation, requête dynamique non maîtrisée | remplacer par requête paramétrée |
| Racine | Confusion donnée / commande | forcer la séparation dès la couche d’accès DB |
| Amplification | Messages d’erreur trop bavards, compte DB trop privilégié | réduire privilèges et surfaces de fuite |
| Détection | Erreurs SQL, variations de temps, anomalies de volume, patterns suspects | corréler applicatif, DB, WAF et SIEM |
Chaîne logique
Entrée HTTP / API / job | v Validation métier | v Construction requête SQL | +--> mauvais : concaténation/interpolation | +--> bon : SQL fixe + paramètres liés | v DB exécute uniquement l’instruction prévue
Détection SOC/SIEM — analyse détaillée
Cette section relie le sujet à la chaîne complète de sécurité applicative : conception, développement, test, déploiement, supervision et réponse à incident. SQL Injection reste un bon exemple de vulnérabilité apparemment “ancienne” mais durable, car elle naît d’un défaut fondamental de séparation entre données et instructions.
- Identifier les entrées qui atteignent la base.
- Séparer valeurs et structure SQL.
- Limiter les privilèges côté base.
- Ajouter tests et contrôles CI/CD.
- Superviser les signaux applicatifs, WAF et DB.
| Point | Détail | Bon réflexe |
|---|---|---|
| Conception | réduire SQL dynamique | patterns repository sûrs |
| Développement | paramètres liés | revue de code systématique |
| Tests | SAST/DAST/lab | preuve corrigée |
| Production | observabilité + WAF | détection rapide |
Détection SOC/SIEM — familles de SQL Injection
| Famille | Principe | Défense prioritaire |
|---|---|---|
| In-band / classique | Résultat ou erreur observable dans la réponse HTTP | prioriser correction du code et masquage erreurs |
| Union-based | Tentative de combiner un résultat contrôlé avec la requête originale | paramétrisation + contrôle strict des colonnes exposées |
| Error-based | Exploitation des erreurs DB pour révéler structure ou données | messages génériques + logs internes |
| Blind boolean | Inférence par différence de réponse vrai/faux | tests automatisés autorisés + monitoring anomalies |
| Blind time-based | Inférence par délai volontaire | timeouts, détection latence anormale, requêtes paramétrées |
| Second-order | Charge stockée puis réutilisée plus tard dans une requête vulnérable | paramétriser aussi les données déjà stockées |
| Stored procedure unsafe | Procédure stockée qui concatène dynamiquement | procédures paramétrées sans EXEC dynamique non contrôlé |
| NoSQL-like analog | Même famille conceptuelle avec moteurs non SQL | séparer données et opérateurs |
' OR '1'='1 -- exemple pédagogique de test en lab
UNION SELECT ... -- à comprendre, pas à utiliser hors environnement autorisé
donnée stockée -> requête ultérieure -> second-order SQLi
Qualifier, contenir, corriger, notifier, apprendre et ajouter les tests de régression.
Objectifs pédagogiques
- Comprendre le mécanisme sans tomber dans la simple liste de payloads.
- Savoir reconnaître les zones à risque dans le code et l’architecture.
- Appliquer une défense en profondeur : code, DB, WAF/WAAP, tests, SOC.
- Transformer le sujet en pratiques industrialisées dans le cycle de développement.
Points de vigilance
| Point | Détail | Bon réflexe |
|---|---|---|
| Cause racine | entrée interprétée comme SQL | séparation données / commandes |
| Correction durable | requêtes paramétrées et allow-list | pas de concaténation |
| Réduction impact | moindre privilège DB | segmentation et audit |
| Contrôle continu | tests + logs + WAF + SOC | feedback loop |
Modèle mental
Réponse à incident | +--> conception sûre +--> code paramétré +--> DB à privilèges minimaux +--> tests contrôlés +--> détection et réponse
Réponse à incident — détection et exploitation SOC
| Source | Signal | Action SOC |
|---|---|---|
| HTTP | pics de 4xx/5xx, paramètres atypiques, erreurs applicatives | alerte corrélée route + user + IP |
| WAF/WAAP | règles injection, score anomalie, répétition payloads | distinguer scan, test interne, attaque |
| DB | erreurs syntaxe, requêtes longues, requêtes inhabituelles | lier à request-id si possible |
| IAM | compte applicatif utilisé hors chemin normal | alerter sur privilèges anormaux |
| Données | volumétrie de lecture/export, accès tables sensibles | détection exfiltration |
request_id=abc123 route=/api/search status=500 waf_rule=SQLI_DETECTED db_error=syntax_error user_id=42
- Corréler les événements avec un identifiant de requête.
- Ne pas se limiter au WAF : une SQLi peut être exploitée via API, batch, mobile ou admin interne.
- Créer un playbook : qualifier, isoler, préserver les preuves, corriger la cause, surveiller la récidive.
- Transformer les incidents en tests de régression et règles de revue de code.
Réponse à incident — prévention robuste
La défense centrale consiste à écrire une requête dont la structure SQL est connue à l’avance, puis à transmettre les valeurs séparément au driver. Le driver gère l’encodage et la liaison des paramètres sans transformer la valeur en fragment SQL.
# Python / psycopg - correct
cursor.execute(
"SELECT id, email FROM users WHERE email = %s",
(email,)
)
# À éviter
cursor.execute("SELECT id FROM users WHERE email = '" + email + "'")Ce qui complète la paramétrisation
- Allow-list pour les noms de colonnes, tris, directions, types de filtres.
- Moindre privilège : compte applicatif limité aux opérations nécessaires.
- Transactions courtes et requêtes lisibles.
- Logs internes utiles sans fuite de SQL brut côté client.
- Tests automatisés unitaires, intégration, DAST contrôlé, revue SAST.
| Élément | Technique sûre | Règle |
|---|---|---|
| Valeurs | paramètres liés | OK |
| Identifiants SQL | allow-list stricte | jamais depuis input libre |
| ORDER BY | mapping champ public -> colonne interne | direction ASC/DESC whitelistée |
| LIMIT/OFFSET | conversion numérique + bornes | pas de texte libre |
Réponse à incident — stratégie de test autorisée
Tester SQLi ne consiste pas à lancer des attaques au hasard. Une démarche professionnelle part d’une cartographie des entrées, puis combine revue de code, tests unitaires de repositories, SAST, DAST sur environnement de test, et validation manuelle encadrée.
- Lister les endpoints, paramètres, filtres, headers, payloads JSON, jobs et imports qui atteignent la DB.
- Identifier les requêtes dynamiques, raw SQL, procédures stockées, query builders et générateurs de rapports.
- Vérifier les paramètres liés, allow-lists et bornes numériques.
- Exécuter les tests uniquement sur environnement autorisé avec données non sensibles.
- Créer des tickets correctifs rattachés aux lignes de code et aux routes concernées.
Cas de tests défensifs
| Zone | Objectif de test | Contrôle attendu |
|---|---|---|
| Login | ne pas différencier erreur SQL / auth invalide | réponse générique + logs internes |
| Recherche | requête paramétrée même avec LIKE | concaténer le wildcard côté valeur, pas SQL |
| Tri | champ et direction par allow-list | mapping serveur |
| Export | mêmes protections que l’API interactive | pas de contournement batch |
| Admin | raw SQL encore plus contrôlé | review obligatoire |
Réponse à incident — gouvernance et industrialisation
- Définir une politique officielle : requêtes paramétrées obligatoires, raw SQL justifié et revu.
- Ajouter des règles de revue : concaténation SQL interdite, tri/colonnes par allow-list.
- Inscrire SQLi dans le threat modeling des features : recherche, reporting, filtres avancés, exports.
- Créer un module de formation développeur avec exemples du stack réel de l’entreprise.
- Mesurer les progrès : dette raw SQL, couverture tests, incidents, temps de correction.
Definition of Done SQLi-safe [ ] aucune concaténation de données dans SQL [ ] paramètres liés pour toutes les valeurs [ ] allow-list pour identifiants SQL dynamiques [ ] tests unitaires repository [ ] logs sans fuite de SQL sensible [ ] privilèges DB minimaux
Réponse à incident — lecture technique
Une injection SQL apparaît lorsqu’une application mélange une donnée fournie par l’utilisateur avec une instruction SQL au lieu de maintenir une séparation stricte entre le code de la requête et les valeurs. Le problème n’est pas le caractère spécial lui-même : c’est le fait que la base interprète une partie de l’entrée comme de la logique SQL.
| Point | Détail | Bon réflexe |
|---|---|---|
| Symptôme | Concaténation de chaînes, interpolation, requête dynamique non maîtrisée | remplacer par requête paramétrée |
| Racine | Confusion donnée / commande | forcer la séparation dès la couche d’accès DB |
| Amplification | Messages d’erreur trop bavards, compte DB trop privilégié | réduire privilèges et surfaces de fuite |
| Détection | Erreurs SQL, variations de temps, anomalies de volume, patterns suspects | corréler applicatif, DB, WAF et SIEM |
Chaîne logique
Entrée HTTP / API / job | v Validation métier | v Construction requête SQL | +--> mauvais : concaténation/interpolation | +--> bon : SQL fixe + paramètres liés | v DB exécute uniquement l’instruction prévue
Réponse à incident — analyse détaillée
Cette section relie le sujet à la chaîne complète de sécurité applicative : conception, développement, test, déploiement, supervision et réponse à incident. SQL Injection reste un bon exemple de vulnérabilité apparemment “ancienne” mais durable, car elle naît d’un défaut fondamental de séparation entre données et instructions.
- Identifier les entrées qui atteignent la base.
- Séparer valeurs et structure SQL.
- Limiter les privilèges côté base.
- Ajouter tests et contrôles CI/CD.
- Superviser les signaux applicatifs, WAF et DB.
| Point | Détail | Bon réflexe |
|---|---|---|
| Conception | réduire SQL dynamique | patterns repository sûrs |
| Développement | paramètres liés | revue de code systématique |
| Tests | SAST/DAST/lab | preuve corrigée |
| Production | observabilité + WAF | détection rapide |
Réponse à incident — exemples de code sécurisé
Django ORM
# Bon : ORM filtre les valeurs
user = User.objects.filter(email=email).first()
# Raw SQL : paramètres obligatoires
User.objects.raw(
"SELECT * FROM app_user WHERE email = %s",
[email]
)Node.js / pg
const result = await client.query( 'SELECT id, email FROM users WHERE email = $1', [email] );
Java / JDBC
PreparedStatement ps = conn.prepareStatement( "SELECT id,email FROM users WHERE email = ?" ); ps.setString(1, email); ResultSet rs = ps.executeQuery();
PHP / PDO
$stmt = $pdo->prepare( 'SELECT id,email FROM users WHERE email = :email' ); $stmt->execute(['email' => $email]);
.NET
using var cmd = new SqlCommand(
"SELECT Id, Email FROM Users WHERE Email = @email", conn);
cmd.Parameters.AddWithValue("@email", email);Go / database/sql
row := db.QueryRowContext(ctx, "SELECT id,email FROM users WHERE email = ?", email, )
Patterns sécurisés pour ORM Django, raw SQL, psycopg, SQLAlchemy et revues de code.
Objectifs pédagogiques
- Comprendre le mécanisme sans tomber dans la simple liste de payloads.
- Savoir reconnaître les zones à risque dans le code et l’architecture.
- Appliquer une défense en profondeur : code, DB, WAF/WAAP, tests, SOC.
- Transformer le sujet en pratiques industrialisées dans le cycle de développement.
Points de vigilance
| Point | Détail | Bon réflexe |
|---|---|---|
| Cause racine | entrée interprétée comme SQL | séparation données / commandes |
| Correction durable | requêtes paramétrées et allow-list | pas de concaténation |
| Réduction impact | moindre privilège DB | segmentation et audit |
| Contrôle continu | tests + logs + WAF + SOC | feedback loop |
Modèle mental
Focus Django/Python | +--> conception sûre +--> code paramétré +--> DB à privilèges minimaux +--> tests contrôlés +--> détection et réponse
Focus Django/Python — prévention robuste
La défense centrale consiste à écrire une requête dont la structure SQL est connue à l’avance, puis à transmettre les valeurs séparément au driver. Le driver gère l’encodage et la liaison des paramètres sans transformer la valeur en fragment SQL.
# Python / psycopg - correct
cursor.execute(
"SELECT id, email FROM users WHERE email = %s",
(email,)
)
# À éviter
cursor.execute("SELECT id FROM users WHERE email = '" + email + "'")Ce qui complète la paramétrisation
- Allow-list pour les noms de colonnes, tris, directions, types de filtres.
- Moindre privilège : compte applicatif limité aux opérations nécessaires.
- Transactions courtes et requêtes lisibles.
- Logs internes utiles sans fuite de SQL brut côté client.
- Tests automatisés unitaires, intégration, DAST contrôlé, revue SAST.
| Élément | Technique sûre | Règle |
|---|---|---|
| Valeurs | paramètres liés | OK |
| Identifiants SQL | allow-list stricte | jamais depuis input libre |
| ORDER BY | mapping champ public -> colonne interne | direction ASC/DESC whitelistée |
| LIMIT/OFFSET | conversion numérique + bornes | pas de texte libre |
Focus Django/Python — stratégie de test autorisée
Tester SQLi ne consiste pas à lancer des attaques au hasard. Une démarche professionnelle part d’une cartographie des entrées, puis combine revue de code, tests unitaires de repositories, SAST, DAST sur environnement de test, et validation manuelle encadrée.
- Lister les endpoints, paramètres, filtres, headers, payloads JSON, jobs et imports qui atteignent la DB.
- Identifier les requêtes dynamiques, raw SQL, procédures stockées, query builders et générateurs de rapports.
- Vérifier les paramètres liés, allow-lists et bornes numériques.
- Exécuter les tests uniquement sur environnement autorisé avec données non sensibles.
- Créer des tickets correctifs rattachés aux lignes de code et aux routes concernées.
Cas de tests défensifs
| Zone | Objectif de test | Contrôle attendu |
|---|---|---|
| Login | ne pas différencier erreur SQL / auth invalide | réponse générique + logs internes |
| Recherche | requête paramétrée même avec LIKE | concaténer le wildcard côté valeur, pas SQL |
| Tri | champ et direction par allow-list | mapping serveur |
| Export | mêmes protections que l’API interactive | pas de contournement batch |
| Admin | raw SQL encore plus contrôlé | review obligatoire |
Focus Django/Python — lecture technique
Une injection SQL apparaît lorsqu’une application mélange une donnée fournie par l’utilisateur avec une instruction SQL au lieu de maintenir une séparation stricte entre le code de la requête et les valeurs. Le problème n’est pas le caractère spécial lui-même : c’est le fait que la base interprète une partie de l’entrée comme de la logique SQL.
| Point | Détail | Bon réflexe |
|---|---|---|
| Symptôme | Concaténation de chaînes, interpolation, requête dynamique non maîtrisée | remplacer par requête paramétrée |
| Racine | Confusion donnée / commande | forcer la séparation dès la couche d’accès DB |
| Amplification | Messages d’erreur trop bavards, compte DB trop privilégié | réduire privilèges et surfaces de fuite |
| Détection | Erreurs SQL, variations de temps, anomalies de volume, patterns suspects | corréler applicatif, DB, WAF et SIEM |
Chaîne logique
Entrée HTTP / API / job | v Validation métier | v Construction requête SQL | +--> mauvais : concaténation/interpolation | +--> bon : SQL fixe + paramètres liés | v DB exécute uniquement l’instruction prévue
Focus Django/Python — gouvernance et industrialisation
- Définir une politique officielle : requêtes paramétrées obligatoires, raw SQL justifié et revu.
- Ajouter des règles de revue : concaténation SQL interdite, tri/colonnes par allow-list.
- Inscrire SQLi dans le threat modeling des features : recherche, reporting, filtres avancés, exports.
- Créer un module de formation développeur avec exemples du stack réel de l’entreprise.
- Mesurer les progrès : dette raw SQL, couverture tests, incidents, temps de correction.
Definition of Done SQLi-safe [ ] aucune concaténation de données dans SQL [ ] paramètres liés pour toutes les valeurs [ ] allow-list pour identifiants SQL dynamiques [ ] tests unitaires repository [ ] logs sans fuite de SQL sensible [ ] privilèges DB minimaux
Focus Django/Python — détection et exploitation SOC
| Source | Signal | Action SOC |
|---|---|---|
| HTTP | pics de 4xx/5xx, paramètres atypiques, erreurs applicatives | alerte corrélée route + user + IP |
| WAF/WAAP | règles injection, score anomalie, répétition payloads | distinguer scan, test interne, attaque |
| DB | erreurs syntaxe, requêtes longues, requêtes inhabituelles | lier à request-id si possible |
| IAM | compte applicatif utilisé hors chemin normal | alerter sur privilèges anormaux |
| Données | volumétrie de lecture/export, accès tables sensibles | détection exfiltration |
request_id=abc123 route=/api/search status=500 waf_rule=SQLI_DETECTED db_error=syntax_error user_id=42
- Corréler les événements avec un identifiant de requête.
- Ne pas se limiter au WAF : une SQLi peut être exploitée via API, batch, mobile ou admin interne.
- Créer un playbook : qualifier, isoler, préserver les preuves, corriger la cause, surveiller la récidive.
- Transformer les incidents en tests de régression et règles de revue de code.
Focus Django/Python — playbook incident SQLi
1. Qualification
- Identifier route, méthode, paramètre, compte utilisateur, IP, fenêtre temporelle.
- Distinguer test interne, scan externe, exploitation probable.
- Préserver logs WAF, app, reverse proxy, DB et audit.
2. Containment
- Désactiver ou filtrer la route si nécessaire.
- Réduire privilèges du compte applicatif si trop large.
- Ajouter règle WAF temporaire ciblée sans masquer le correctif code.
3. Éradication
- Corriger concaténation/raw SQL.
- Ajouter tests de régression.
- Revoir endpoints similaires.
- Déployer avec rollback possible.
| Sujet | À documenter | Livrable |
|---|---|---|
| Preuves | logs horodatés, payloads, réponses, erreurs DB, traces | chaîne de conservation |
| Données | tables lues/modifiées, exports, comptes affectés | analyse d’impact |
| Communication | juridique, DPO, RSSI, métiers, client si nécessaire | message factuel |
| Post-mortem | racine, délai détection, tests manquants, ownership | plan d’actions |
Focus Django/Python — analyse détaillée
Cette section relie le sujet à la chaîne complète de sécurité applicative : conception, développement, test, déploiement, supervision et réponse à incident. SQL Injection reste un bon exemple de vulnérabilité apparemment “ancienne” mais durable, car elle naît d’un défaut fondamental de séparation entre données et instructions.
- Identifier les entrées qui atteignent la base.
- Séparer valeurs et structure SQL.
- Limiter les privilèges côté base.
- Ajouter tests et contrôles CI/CD.
- Superviser les signaux applicatifs, WAF et DB.
| Point | Détail | Bon réflexe |
|---|---|---|
| Conception | réduire SQL dynamique | patterns repository sûrs |
| Développement | paramètres liés | revue de code systématique |
| Tests | SAST/DAST/lab | preuve corrigée |
| Production | observabilité + WAF | détection rapide |
Node, Java, PHP, .NET, Go : repères de paramétrisation par stack.
Objectifs pédagogiques
- Comprendre le mécanisme sans tomber dans la simple liste de payloads.
- Savoir reconnaître les zones à risque dans le code et l’architecture.
- Appliquer une défense en profondeur : code, DB, WAF/WAAP, tests, SOC.
- Transformer le sujet en pratiques industrialisées dans le cycle de développement.
Points de vigilance
| Point | Détail | Bon réflexe |
|---|---|---|
| Cause racine | entrée interprétée comme SQL | séparation données / commandes |
| Correction durable | requêtes paramétrées et allow-list | pas de concaténation |
| Réduction impact | moindre privilège DB | segmentation et audit |
| Contrôle continu | tests + logs + WAF + SOC | feedback loop |
Modèle mental
Snippets multi-langages | +--> conception sûre +--> code paramétré +--> DB à privilèges minimaux +--> tests contrôlés +--> détection et réponse
Snippets multi-langages — prévention robuste
La défense centrale consiste à écrire une requête dont la structure SQL est connue à l’avance, puis à transmettre les valeurs séparément au driver. Le driver gère l’encodage et la liaison des paramètres sans transformer la valeur en fragment SQL.
# Python / psycopg - correct
cursor.execute(
"SELECT id, email FROM users WHERE email = %s",
(email,)
)
# À éviter
cursor.execute("SELECT id FROM users WHERE email = '" + email + "'")Ce qui complète la paramétrisation
- Allow-list pour les noms de colonnes, tris, directions, types de filtres.
- Moindre privilège : compte applicatif limité aux opérations nécessaires.
- Transactions courtes et requêtes lisibles.
- Logs internes utiles sans fuite de SQL brut côté client.
- Tests automatisés unitaires, intégration, DAST contrôlé, revue SAST.
| Élément | Technique sûre | Règle |
|---|---|---|
| Valeurs | paramètres liés | OK |
| Identifiants SQL | allow-list stricte | jamais depuis input libre |
| ORDER BY | mapping champ public -> colonne interne | direction ASC/DESC whitelistée |
| LIMIT/OFFSET | conversion numérique + bornes | pas de texte libre |
Snippets multi-langages — stratégie de test autorisée
Tester SQLi ne consiste pas à lancer des attaques au hasard. Une démarche professionnelle part d’une cartographie des entrées, puis combine revue de code, tests unitaires de repositories, SAST, DAST sur environnement de test, et validation manuelle encadrée.
- Lister les endpoints, paramètres, filtres, headers, payloads JSON, jobs et imports qui atteignent la DB.
- Identifier les requêtes dynamiques, raw SQL, procédures stockées, query builders et générateurs de rapports.
- Vérifier les paramètres liés, allow-lists et bornes numériques.
- Exécuter les tests uniquement sur environnement autorisé avec données non sensibles.
- Créer des tickets correctifs rattachés aux lignes de code et aux routes concernées.
Cas de tests défensifs
| Zone | Objectif de test | Contrôle attendu |
|---|---|---|
| Login | ne pas différencier erreur SQL / auth invalide | réponse générique + logs internes |
| Recherche | requête paramétrée même avec LIKE | concaténer le wildcard côté valeur, pas SQL |
| Tri | champ et direction par allow-list | mapping serveur |
| Export | mêmes protections que l’API interactive | pas de contournement batch |
| Admin | raw SQL encore plus contrôlé | review obligatoire |
Snippets multi-langages — gouvernance et industrialisation
- Définir une politique officielle : requêtes paramétrées obligatoires, raw SQL justifié et revu.
- Ajouter des règles de revue : concaténation SQL interdite, tri/colonnes par allow-list.
- Inscrire SQLi dans le threat modeling des features : recherche, reporting, filtres avancés, exports.
- Créer un module de formation développeur avec exemples du stack réel de l’entreprise.
- Mesurer les progrès : dette raw SQL, couverture tests, incidents, temps de correction.
Definition of Done SQLi-safe [ ] aucune concaténation de données dans SQL [ ] paramètres liés pour toutes les valeurs [ ] allow-list pour identifiants SQL dynamiques [ ] tests unitaires repository [ ] logs sans fuite de SQL sensible [ ] privilèges DB minimaux
Snippets multi-langages — lecture technique
Une injection SQL apparaît lorsqu’une application mélange une donnée fournie par l’utilisateur avec une instruction SQL au lieu de maintenir une séparation stricte entre le code de la requête et les valeurs. Le problème n’est pas le caractère spécial lui-même : c’est le fait que la base interprète une partie de l’entrée comme de la logique SQL.
| Point | Détail | Bon réflexe |
|---|---|---|
| Symptôme | Concaténation de chaînes, interpolation, requête dynamique non maîtrisée | remplacer par requête paramétrée |
| Racine | Confusion donnée / commande | forcer la séparation dès la couche d’accès DB |
| Amplification | Messages d’erreur trop bavards, compte DB trop privilégié | réduire privilèges et surfaces de fuite |
| Détection | Erreurs SQL, variations de temps, anomalies de volume, patterns suspects | corréler applicatif, DB, WAF et SIEM |
Chaîne logique
Entrée HTTP / API / job | v Validation métier | v Construction requête SQL | +--> mauvais : concaténation/interpolation | +--> bon : SQL fixe + paramètres liés | v DB exécute uniquement l’instruction prévue
Snippets multi-langages — détection et exploitation SOC
| Source | Signal | Action SOC |
|---|---|---|
| HTTP | pics de 4xx/5xx, paramètres atypiques, erreurs applicatives | alerte corrélée route + user + IP |
| WAF/WAAP | règles injection, score anomalie, répétition payloads | distinguer scan, test interne, attaque |
| DB | erreurs syntaxe, requêtes longues, requêtes inhabituelles | lier à request-id si possible |
| IAM | compte applicatif utilisé hors chemin normal | alerter sur privilèges anormaux |
| Données | volumétrie de lecture/export, accès tables sensibles | détection exfiltration |
request_id=abc123 route=/api/search status=500 waf_rule=SQLI_DETECTED db_error=syntax_error user_id=42
- Corréler les événements avec un identifiant de requête.
- Ne pas se limiter au WAF : une SQLi peut être exploitée via API, batch, mobile ou admin interne.
- Créer un playbook : qualifier, isoler, préserver les preuves, corriger la cause, surveiller la récidive.
- Transformer les incidents en tests de régression et règles de revue de code.
Snippets multi-langages — playbook incident SQLi
1. Qualification
- Identifier route, méthode, paramètre, compte utilisateur, IP, fenêtre temporelle.
- Distinguer test interne, scan externe, exploitation probable.
- Préserver logs WAF, app, reverse proxy, DB et audit.
2. Containment
- Désactiver ou filtrer la route si nécessaire.
- Réduire privilèges du compte applicatif si trop large.
- Ajouter règle WAF temporaire ciblée sans masquer le correctif code.
3. Éradication
- Corriger concaténation/raw SQL.
- Ajouter tests de régression.
- Revoir endpoints similaires.
- Déployer avec rollback possible.
| Sujet | À documenter | Livrable |
|---|---|---|
| Preuves | logs horodatés, payloads, réponses, erreurs DB, traces | chaîne de conservation |
| Données | tables lues/modifiées, exports, comptes affectés | analyse d’impact |
| Communication | juridique, DPO, RSSI, métiers, client si nécessaire | message factuel |
| Post-mortem | racine, délai détection, tests manquants, ownership | plan d’actions |
Snippets multi-langages — analyse détaillée
Cette section relie le sujet à la chaîne complète de sécurité applicative : conception, développement, test, déploiement, supervision et réponse à incident. SQL Injection reste un bon exemple de vulnérabilité apparemment “ancienne” mais durable, car elle naît d’un défaut fondamental de séparation entre données et instructions.
- Identifier les entrées qui atteignent la base.
- Séparer valeurs et structure SQL.
- Limiter les privilèges côté base.
- Ajouter tests et contrôles CI/CD.
- Superviser les signaux applicatifs, WAF et DB.
| Point | Détail | Bon réflexe |
|---|---|---|
| Conception | réduire SQL dynamique | patterns repository sûrs |
| Développement | paramètres liés | revue de code systématique |
| Tests | SAST/DAST/lab | preuve corrigée |
| Production | observabilité + WAF | détection rapide |
Transformer une base ancienne vulnérable sans tout casser : inventaire, priorisation, patchs sûrs.
Objectifs pédagogiques
- Comprendre le mécanisme sans tomber dans la simple liste de payloads.
- Savoir reconnaître les zones à risque dans le code et l’architecture.
- Appliquer une défense en profondeur : code, DB, WAF/WAAP, tests, SOC.
- Transformer le sujet en pratiques industrialisées dans le cycle de développement.
Points de vigilance
| Point | Détail | Bon réflexe |
|---|---|---|
| Cause racine | entrée interprétée comme SQL | séparation données / commandes |
| Correction durable | requêtes paramétrées et allow-list | pas de concaténation |
| Réduction impact | moindre privilège DB | segmentation et audit |
| Contrôle continu | tests + logs + WAF + SOC | feedback loop |
Modèle mental
Remédiation legacy | +--> conception sûre +--> code paramétré +--> DB à privilèges minimaux +--> tests contrôlés +--> détection et réponse
Remédiation legacy — stratégie de test autorisée
Tester SQLi ne consiste pas à lancer des attaques au hasard. Une démarche professionnelle part d’une cartographie des entrées, puis combine revue de code, tests unitaires de repositories, SAST, DAST sur environnement de test, et validation manuelle encadrée.
- Lister les endpoints, paramètres, filtres, headers, payloads JSON, jobs et imports qui atteignent la DB.
- Identifier les requêtes dynamiques, raw SQL, procédures stockées, query builders et générateurs de rapports.
- Vérifier les paramètres liés, allow-lists et bornes numériques.
- Exécuter les tests uniquement sur environnement autorisé avec données non sensibles.
- Créer des tickets correctifs rattachés aux lignes de code et aux routes concernées.
Cas de tests défensifs
| Zone | Objectif de test | Contrôle attendu |
|---|---|---|
| Login | ne pas différencier erreur SQL / auth invalide | réponse générique + logs internes |
| Recherche | requête paramétrée même avec LIKE | concaténer le wildcard côté valeur, pas SQL |
| Tri | champ et direction par allow-list | mapping serveur |
| Export | mêmes protections que l’API interactive | pas de contournement batch |
| Admin | raw SQL encore plus contrôlé | review obligatoire |
Remédiation legacy — prévention robuste
La défense centrale consiste à écrire une requête dont la structure SQL est connue à l’avance, puis à transmettre les valeurs séparément au driver. Le driver gère l’encodage et la liaison des paramètres sans transformer la valeur en fragment SQL.
# Python / psycopg - correct
cursor.execute(
"SELECT id, email FROM users WHERE email = %s",
(email,)
)
# À éviter
cursor.execute("SELECT id FROM users WHERE email = '" + email + "'")Ce qui complète la paramétrisation
- Allow-list pour les noms de colonnes, tris, directions, types de filtres.
- Moindre privilège : compte applicatif limité aux opérations nécessaires.
- Transactions courtes et requêtes lisibles.
- Logs internes utiles sans fuite de SQL brut côté client.
- Tests automatisés unitaires, intégration, DAST contrôlé, revue SAST.
| Élément | Technique sûre | Règle |
|---|---|---|
| Valeurs | paramètres liés | OK |
| Identifiants SQL | allow-list stricte | jamais depuis input libre |
| ORDER BY | mapping champ public -> colonne interne | direction ASC/DESC whitelistée |
| LIMIT/OFFSET | conversion numérique + bornes | pas de texte libre |
Remédiation legacy — playbook incident SQLi
1. Qualification
- Identifier route, méthode, paramètre, compte utilisateur, IP, fenêtre temporelle.
- Distinguer test interne, scan externe, exploitation probable.
- Préserver logs WAF, app, reverse proxy, DB et audit.
2. Containment
- Désactiver ou filtrer la route si nécessaire.
- Réduire privilèges du compte applicatif si trop large.
- Ajouter règle WAF temporaire ciblée sans masquer le correctif code.
3. Éradication
- Corriger concaténation/raw SQL.
- Ajouter tests de régression.
- Revoir endpoints similaires.
- Déployer avec rollback possible.
| Sujet | À documenter | Livrable |
|---|---|---|
| Preuves | logs horodatés, payloads, réponses, erreurs DB, traces | chaîne de conservation |
| Données | tables lues/modifiées, exports, comptes affectés | analyse d’impact |
| Communication | juridique, DPO, RSSI, métiers, client si nécessaire | message factuel |
| Post-mortem | racine, délai détection, tests manquants, ownership | plan d’actions |
Remédiation legacy — détection et exploitation SOC
| Source | Signal | Action SOC |
|---|---|---|
| HTTP | pics de 4xx/5xx, paramètres atypiques, erreurs applicatives | alerte corrélée route + user + IP |
| WAF/WAAP | règles injection, score anomalie, répétition payloads | distinguer scan, test interne, attaque |
| DB | erreurs syntaxe, requêtes longues, requêtes inhabituelles | lier à request-id si possible |
| IAM | compte applicatif utilisé hors chemin normal | alerter sur privilèges anormaux |
| Données | volumétrie de lecture/export, accès tables sensibles | détection exfiltration |
request_id=abc123 route=/api/search status=500 waf_rule=SQLI_DETECTED db_error=syntax_error user_id=42
- Corréler les événements avec un identifiant de requête.
- Ne pas se limiter au WAF : une SQLi peut être exploitée via API, batch, mobile ou admin interne.
- Créer un playbook : qualifier, isoler, préserver les preuves, corriger la cause, surveiller la récidive.
- Transformer les incidents en tests de régression et règles de revue de code.
Remédiation legacy — lecture technique
Une injection SQL apparaît lorsqu’une application mélange une donnée fournie par l’utilisateur avec une instruction SQL au lieu de maintenir une séparation stricte entre le code de la requête et les valeurs. Le problème n’est pas le caractère spécial lui-même : c’est le fait que la base interprète une partie de l’entrée comme de la logique SQL.
| Point | Détail | Bon réflexe |
|---|---|---|
| Symptôme | Concaténation de chaînes, interpolation, requête dynamique non maîtrisée | remplacer par requête paramétrée |
| Racine | Confusion donnée / commande | forcer la séparation dès la couche d’accès DB |
| Amplification | Messages d’erreur trop bavards, compte DB trop privilégié | réduire privilèges et surfaces de fuite |
| Détection | Erreurs SQL, variations de temps, anomalies de volume, patterns suspects | corréler applicatif, DB, WAF et SIEM |
Chaîne logique
Entrée HTTP / API / job | v Validation métier | v Construction requête SQL | +--> mauvais : concaténation/interpolation | +--> bon : SQL fixe + paramètres liés | v DB exécute uniquement l’instruction prévue
Remédiation legacy — analyse détaillée
Cette section relie le sujet à la chaîne complète de sécurité applicative : conception, développement, test, déploiement, supervision et réponse à incident. SQL Injection reste un bon exemple de vulnérabilité apparemment “ancienne” mais durable, car elle naît d’un défaut fondamental de séparation entre données et instructions.
- Identifier les entrées qui atteignent la base.
- Séparer valeurs et structure SQL.
- Limiter les privilèges côté base.
- Ajouter tests et contrôles CI/CD.
- Superviser les signaux applicatifs, WAF et DB.
| Point | Détail | Bon réflexe |
|---|---|---|
| Conception | réduire SQL dynamique | patterns repository sûrs |
| Développement | paramètres liés | revue de code systématique |
| Tests | SAST/DAST/lab | preuve corrigée |
| Production | observabilité + WAF | détection rapide |
Remédiation legacy — exemples de code sécurisé
Django ORM
# Bon : ORM filtre les valeurs
user = User.objects.filter(email=email).first()
# Raw SQL : paramètres obligatoires
User.objects.raw(
"SELECT * FROM app_user WHERE email = %s",
[email]
)Node.js / pg
const result = await client.query( 'SELECT id, email FROM users WHERE email = $1', [email] );
Java / JDBC
PreparedStatement ps = conn.prepareStatement( "SELECT id,email FROM users WHERE email = ?" ); ps.setString(1, email); ResultSet rs = ps.executeQuery();
PHP / PDO
$stmt = $pdo->prepare( 'SELECT id,email FROM users WHERE email = :email' ); $stmt->execute(['email' => $email]);
.NET
using var cmd = new SqlCommand(
"SELECT Id, Email FROM Users WHERE Email = @email", conn);
cmd.Parameters.AddWithValue("@email", email);Go / database/sql
row := db.QueryRowContext(ctx, "SELECT id,email FROM users WHERE email = ?", email, )
Ateliers, kata, revues, checklists, anti-patterns et culture secure coding.
Objectifs pédagogiques
- Comprendre le mécanisme sans tomber dans la simple liste de payloads.
- Savoir reconnaître les zones à risque dans le code et l’architecture.
- Appliquer une défense en profondeur : code, DB, WAF/WAAP, tests, SOC.
- Transformer le sujet en pratiques industrialisées dans le cycle de développement.
Points de vigilance
| Point | Détail | Bon réflexe |
|---|---|---|
| Cause racine | entrée interprétée comme SQL | séparation données / commandes |
| Correction durable | requêtes paramétrées et allow-list | pas de concaténation |
| Réduction impact | moindre privilège DB | segmentation et audit |
| Contrôle continu | tests + logs + WAF + SOC | feedback loop |
Modèle mental
Formation développeurs | +--> conception sûre +--> code paramétré +--> DB à privilèges minimaux +--> tests contrôlés +--> détection et réponse
Formation développeurs — exemples de code sécurisé
Django ORM
# Bon : ORM filtre les valeurs
user = User.objects.filter(email=email).first()
# Raw SQL : paramètres obligatoires
User.objects.raw(
"SELECT * FROM app_user WHERE email = %s",
[email]
)Node.js / pg
const result = await client.query( 'SELECT id, email FROM users WHERE email = $1', [email] );
Java / JDBC
PreparedStatement ps = conn.prepareStatement( "SELECT id,email FROM users WHERE email = ?" ); ps.setString(1, email); ResultSet rs = ps.executeQuery();
PHP / PDO
$stmt = $pdo->prepare( 'SELECT id,email FROM users WHERE email = :email' ); $stmt->execute(['email' => $email]);
.NET
using var cmd = new SqlCommand(
"SELECT Id, Email FROM Users WHERE Email = @email", conn);
cmd.Parameters.AddWithValue("@email", email);Go / database/sql
row := db.QueryRowContext(ctx, "SELECT id,email FROM users WHERE email = ?", email, )
Formation développeurs — stratégie de test autorisée
Tester SQLi ne consiste pas à lancer des attaques au hasard. Une démarche professionnelle part d’une cartographie des entrées, puis combine revue de code, tests unitaires de repositories, SAST, DAST sur environnement de test, et validation manuelle encadrée.
- Lister les endpoints, paramètres, filtres, headers, payloads JSON, jobs et imports qui atteignent la DB.
- Identifier les requêtes dynamiques, raw SQL, procédures stockées, query builders et générateurs de rapports.
- Vérifier les paramètres liés, allow-lists et bornes numériques.
- Exécuter les tests uniquement sur environnement autorisé avec données non sensibles.
- Créer des tickets correctifs rattachés aux lignes de code et aux routes concernées.
Cas de tests défensifs
| Zone | Objectif de test | Contrôle attendu |
|---|---|---|
| Login | ne pas différencier erreur SQL / auth invalide | réponse générique + logs internes |
| Recherche | requête paramétrée même avec LIKE | concaténer le wildcard côté valeur, pas SQL |
| Tri | champ et direction par allow-list | mapping serveur |
| Export | mêmes protections que l’API interactive | pas de contournement batch |
| Admin | raw SQL encore plus contrôlé | review obligatoire |
Formation développeurs — prévention robuste
La défense centrale consiste à écrire une requête dont la structure SQL est connue à l’avance, puis à transmettre les valeurs séparément au driver. Le driver gère l’encodage et la liaison des paramètres sans transformer la valeur en fragment SQL.
# Python / psycopg - correct
cursor.execute(
"SELECT id, email FROM users WHERE email = %s",
(email,)
)
# À éviter
cursor.execute("SELECT id FROM users WHERE email = '" + email + "'")Ce qui complète la paramétrisation
- Allow-list pour les noms de colonnes, tris, directions, types de filtres.
- Moindre privilège : compte applicatif limité aux opérations nécessaires.
- Transactions courtes et requêtes lisibles.
- Logs internes utiles sans fuite de SQL brut côté client.
- Tests automatisés unitaires, intégration, DAST contrôlé, revue SAST.
| Élément | Technique sûre | Règle |
|---|---|---|
| Valeurs | paramètres liés | OK |
| Identifiants SQL | allow-list stricte | jamais depuis input libre |
| ORDER BY | mapping champ public -> colonne interne | direction ASC/DESC whitelistée |
| LIMIT/OFFSET | conversion numérique + bornes | pas de texte libre |
Formation développeurs — lecture technique
Une injection SQL apparaît lorsqu’une application mélange une donnée fournie par l’utilisateur avec une instruction SQL au lieu de maintenir une séparation stricte entre le code de la requête et les valeurs. Le problème n’est pas le caractère spécial lui-même : c’est le fait que la base interprète une partie de l’entrée comme de la logique SQL.
| Point | Détail | Bon réflexe |
|---|---|---|
| Symptôme | Concaténation de chaînes, interpolation, requête dynamique non maîtrisée | remplacer par requête paramétrée |
| Racine | Confusion donnée / commande | forcer la séparation dès la couche d’accès DB |
| Amplification | Messages d’erreur trop bavards, compte DB trop privilégié | réduire privilèges et surfaces de fuite |
| Détection | Erreurs SQL, variations de temps, anomalies de volume, patterns suspects | corréler applicatif, DB, WAF et SIEM |
Chaîne logique
Entrée HTTP / API / job | v Validation métier | v Construction requête SQL | +--> mauvais : concaténation/interpolation | +--> bon : SQL fixe + paramètres liés | v DB exécute uniquement l’instruction prévue
Formation développeurs — détection et exploitation SOC
| Source | Signal | Action SOC |
|---|---|---|
| HTTP | pics de 4xx/5xx, paramètres atypiques, erreurs applicatives | alerte corrélée route + user + IP |
| WAF/WAAP | règles injection, score anomalie, répétition payloads | distinguer scan, test interne, attaque |
| DB | erreurs syntaxe, requêtes longues, requêtes inhabituelles | lier à request-id si possible |
| IAM | compte applicatif utilisé hors chemin normal | alerter sur privilèges anormaux |
| Données | volumétrie de lecture/export, accès tables sensibles | détection exfiltration |
request_id=abc123 route=/api/search status=500 waf_rule=SQLI_DETECTED db_error=syntax_error user_id=42
- Corréler les événements avec un identifiant de requête.
- Ne pas se limiter au WAF : une SQLi peut être exploitée via API, batch, mobile ou admin interne.
- Créer un playbook : qualifier, isoler, préserver les preuves, corriger la cause, surveiller la récidive.
- Transformer les incidents en tests de régression et règles de revue de code.
Formation développeurs — playbook incident SQLi
1. Qualification
- Identifier route, méthode, paramètre, compte utilisateur, IP, fenêtre temporelle.
- Distinguer test interne, scan externe, exploitation probable.
- Préserver logs WAF, app, reverse proxy, DB et audit.
2. Containment
- Désactiver ou filtrer la route si nécessaire.
- Réduire privilèges du compte applicatif si trop large.
- Ajouter règle WAF temporaire ciblée sans masquer le correctif code.
3. Éradication
- Corriger concaténation/raw SQL.
- Ajouter tests de régression.
- Revoir endpoints similaires.
- Déployer avec rollback possible.
| Sujet | À documenter | Livrable |
|---|---|---|
| Preuves | logs horodatés, payloads, réponses, erreurs DB, traces | chaîne de conservation |
| Données | tables lues/modifiées, exports, comptes affectés | analyse d’impact |
| Communication | juridique, DPO, RSSI, métiers, client si nécessaire | message factuel |
| Post-mortem | racine, délai détection, tests manquants, ownership | plan d’actions |
Formation développeurs — analyse détaillée
Cette section relie le sujet à la chaîne complète de sécurité applicative : conception, développement, test, déploiement, supervision et réponse à incident. SQL Injection reste un bon exemple de vulnérabilité apparemment “ancienne” mais durable, car elle naît d’un défaut fondamental de séparation entre données et instructions.
- Identifier les entrées qui atteignent la base.
- Séparer valeurs et structure SQL.
- Limiter les privilèges côté base.
- Ajouter tests et contrôles CI/CD.
- Superviser les signaux applicatifs, WAF et DB.
| Point | Détail | Bon réflexe |
|---|---|---|
| Conception | réduire SQL dynamique | patterns repository sûrs |
| Développement | paramètres liés | revue de code systématique |
| Tests | SAST/DAST/lab | preuve corrigée |
| Production | observabilité + WAF | détection rapide |
Résumé opérationnel, checklists, roadmap 30/60/90 jours et référentiels.
Objectifs pédagogiques
- Comprendre le mécanisme sans tomber dans la simple liste de payloads.
- Savoir reconnaître les zones à risque dans le code et l’architecture.
- Appliquer une défense en profondeur : code, DB, WAF/WAAP, tests, SOC.
- Transformer le sujet en pratiques industrialisées dans le cycle de développement.
Points de vigilance
| Point | Détail | Bon réflexe |
|---|---|---|
| Cause racine | entrée interprétée comme SQL | séparation données / commandes |
| Correction durable | requêtes paramétrées et allow-list | pas de concaténation |
| Réduction impact | moindre privilège DB | segmentation et audit |
| Contrôle continu | tests + logs + WAF + SOC | feedback loop |
Modèle mental
Cheat-sheet & roadmap | +--> conception sûre +--> code paramétré +--> DB à privilèges minimaux +--> tests contrôlés +--> détection et réponse
Cheat-sheet & roadmap — prévention robuste
La défense centrale consiste à écrire une requête dont la structure SQL est connue à l’avance, puis à transmettre les valeurs séparément au driver. Le driver gère l’encodage et la liaison des paramètres sans transformer la valeur en fragment SQL.
# Python / psycopg - correct
cursor.execute(
"SELECT id, email FROM users WHERE email = %s",
(email,)
)
# À éviter
cursor.execute("SELECT id FROM users WHERE email = '" + email + "'")Ce qui complète la paramétrisation
- Allow-list pour les noms de colonnes, tris, directions, types de filtres.
- Moindre privilège : compte applicatif limité aux opérations nécessaires.
- Transactions courtes et requêtes lisibles.
- Logs internes utiles sans fuite de SQL brut côté client.
- Tests automatisés unitaires, intégration, DAST contrôlé, revue SAST.
| Élément | Technique sûre | Règle |
|---|---|---|
| Valeurs | paramètres liés | OK |
| Identifiants SQL | allow-list stricte | jamais depuis input libre |
| ORDER BY | mapping champ public -> colonne interne | direction ASC/DESC whitelistée |
| LIMIT/OFFSET | conversion numérique + bornes | pas de texte libre |
Cheat-sheet & roadmap — stratégie de test autorisée
Tester SQLi ne consiste pas à lancer des attaques au hasard. Une démarche professionnelle part d’une cartographie des entrées, puis combine revue de code, tests unitaires de repositories, SAST, DAST sur environnement de test, et validation manuelle encadrée.
- Lister les endpoints, paramètres, filtres, headers, payloads JSON, jobs et imports qui atteignent la DB.
- Identifier les requêtes dynamiques, raw SQL, procédures stockées, query builders et générateurs de rapports.
- Vérifier les paramètres liés, allow-lists et bornes numériques.
- Exécuter les tests uniquement sur environnement autorisé avec données non sensibles.
- Créer des tickets correctifs rattachés aux lignes de code et aux routes concernées.
Cas de tests défensifs
| Zone | Objectif de test | Contrôle attendu |
|---|---|---|
| Login | ne pas différencier erreur SQL / auth invalide | réponse générique + logs internes |
| Recherche | requête paramétrée même avec LIKE | concaténer le wildcard côté valeur, pas SQL |
| Tri | champ et direction par allow-list | mapping serveur |
| Export | mêmes protections que l’API interactive | pas de contournement batch |
| Admin | raw SQL encore plus contrôlé | review obligatoire |
Cheat-sheet & roadmap — détection et exploitation SOC
| Source | Signal | Action SOC |
|---|---|---|
| HTTP | pics de 4xx/5xx, paramètres atypiques, erreurs applicatives | alerte corrélée route + user + IP |
| WAF/WAAP | règles injection, score anomalie, répétition payloads | distinguer scan, test interne, attaque |
| DB | erreurs syntaxe, requêtes longues, requêtes inhabituelles | lier à request-id si possible |
| IAM | compte applicatif utilisé hors chemin normal | alerter sur privilèges anormaux |
| Données | volumétrie de lecture/export, accès tables sensibles | détection exfiltration |
request_id=abc123 route=/api/search status=500 waf_rule=SQLI_DETECTED db_error=syntax_error user_id=42
- Corréler les événements avec un identifiant de requête.
- Ne pas se limiter au WAF : une SQLi peut être exploitée via API, batch, mobile ou admin interne.
- Créer un playbook : qualifier, isoler, préserver les preuves, corriger la cause, surveiller la récidive.
- Transformer les incidents en tests de régression et règles de revue de code.
Cheat-sheet & roadmap — playbook incident SQLi
1. Qualification
- Identifier route, méthode, paramètre, compte utilisateur, IP, fenêtre temporelle.
- Distinguer test interne, scan externe, exploitation probable.
- Préserver logs WAF, app, reverse proxy, DB et audit.
2. Containment
- Désactiver ou filtrer la route si nécessaire.
- Réduire privilèges du compte applicatif si trop large.
- Ajouter règle WAF temporaire ciblée sans masquer le correctif code.
3. Éradication
- Corriger concaténation/raw SQL.
- Ajouter tests de régression.
- Revoir endpoints similaires.
- Déployer avec rollback possible.
| Sujet | À documenter | Livrable |
|---|---|---|
| Preuves | logs horodatés, payloads, réponses, erreurs DB, traces | chaîne de conservation |
| Données | tables lues/modifiées, exports, comptes affectés | analyse d’impact |
| Communication | juridique, DPO, RSSI, métiers, client si nécessaire | message factuel |
| Post-mortem | racine, délai détection, tests manquants, ownership | plan d’actions |
Cheat-sheet & roadmap — exemples de code sécurisé
Django ORM
# Bon : ORM filtre les valeurs
user = User.objects.filter(email=email).first()
# Raw SQL : paramètres obligatoires
User.objects.raw(
"SELECT * FROM app_user WHERE email = %s",
[email]
)Node.js / pg
const result = await client.query( 'SELECT id, email FROM users WHERE email = $1', [email] );
Java / JDBC
PreparedStatement ps = conn.prepareStatement( "SELECT id,email FROM users WHERE email = ?" ); ps.setString(1, email); ResultSet rs = ps.executeQuery();
PHP / PDO
$stmt = $pdo->prepare( 'SELECT id,email FROM users WHERE email = :email' ); $stmt->execute(['email' => $email]);
.NET
using var cmd = new SqlCommand(
"SELECT Id, Email FROM Users WHERE Email = @email", conn);
cmd.Parameters.AddWithValue("@email", email);Go / database/sql
row := db.QueryRowContext(ctx, "SELECT id,email FROM users WHERE email = ?", email, )
Cheat-sheet & roadmap — lecture technique
Une injection SQL apparaît lorsqu’une application mélange une donnée fournie par l’utilisateur avec une instruction SQL au lieu de maintenir une séparation stricte entre le code de la requête et les valeurs. Le problème n’est pas le caractère spécial lui-même : c’est le fait que la base interprète une partie de l’entrée comme de la logique SQL.
| Point | Détail | Bon réflexe |
|---|---|---|
| Symptôme | Concaténation de chaînes, interpolation, requête dynamique non maîtrisée | remplacer par requête paramétrée |
| Racine | Confusion donnée / commande | forcer la séparation dès la couche d’accès DB |
| Amplification | Messages d’erreur trop bavards, compte DB trop privilégié | réduire privilèges et surfaces de fuite |
| Détection | Erreurs SQL, variations de temps, anomalies de volume, patterns suspects | corréler applicatif, DB, WAF et SIEM |
Chaîne logique
Entrée HTTP / API / job | v Validation métier | v Construction requête SQL | +--> mauvais : concaténation/interpolation | +--> bon : SQL fixe + paramètres liés | v DB exécute uniquement l’instruction prévue
Cheat-sheet & roadmap — analyse détaillée
Cette section relie le sujet à la chaîne complète de sécurité applicative : conception, développement, test, déploiement, supervision et réponse à incident. SQL Injection reste un bon exemple de vulnérabilité apparemment “ancienne” mais durable, car elle naît d’un défaut fondamental de séparation entre données et instructions.
- Identifier les entrées qui atteignent la base.
- Séparer valeurs et structure SQL.
- Limiter les privilèges côté base.
- Ajouter tests et contrôles CI/CD.
- Superviser les signaux applicatifs, WAF et DB.
| Point | Détail | Bon réflexe |
|---|---|---|
| Conception | réduire SQL dynamique | patterns repository sûrs |
| Développement | paramètres liés | revue de code systématique |
| Tests | SAST/DAST/lab | preuve corrigée |
| Production | observabilité + WAF | détection rapide |
