OWASP Checker
Workflow
Étape 1 — Cadrage initial
Avant d'auditer, demande (ou infère du contexte) :
- Stack : langage, framework, ORM, moteur de template
- Type : web MPA, SPA+API, API REST/GraphQL, microservices, mobile backend
- Scope : toute l'app ou un composant précis (auth, paiement, upload…)
- Profondeur : revue de code statique / checklist / test dynamique (pentest)
Adapte les catégories à auditer : une API sans UI n'a pas de XSS stocké, un monolithe sans Docker n'a pas de misconfiguration container.
Étape 2 — A01 Broken Access Control (criticité : critique)
Vérifications clés :
- Chaque endpoint applique l'autorisation côté serveur (jamais côté client)
- Pas d'IDOR : les IDs en URL/paramètres sont vérifiés contre l'utilisateur courant
- Pas de force browsing : les routes protégées retournent 401/403, pas 200
- Séparation des rôles testée (admin, user, guest)
Exemple de faille IDOR — Node.js Express :
// ❌ Vulnérable
app.get('/orders/:id', auth, (req, res) => {
db.query('SELECT * FROM orders WHERE id = ?', [req.params.id]);
});
// ✅ Corrigé
app.get('/orders/:id', auth, (req, res) => {
db.query('SELECT * FROM orders WHERE id = ? AND user_id = ?',
[req.params.id, req.user.id]);
});
Commande de test rapide :
# Tester l'accès cross-user avec curl
curl -H "Authorization: Bearer <token_user_A>" https://api.example.com/orders/42
# 42 appartient à user B → doit retourner 403, pas les données
Étape 3 — A02 Cryptographic Failures (criticité : critique)
Checklist :
Scan de secrets dans git :
# Installer gitleaks et scanner le repo complet
docker run -v $(pwd):/path zricethezav/gitleaks:latest detect --source /path --verbose
Hashing correct en Node.js :
import bcrypt from 'bcrypt';
// ✅ cost factor 12, résistant aux GPU
const hash = await bcrypt.hash(password, 12);
const ok = await bcrypt.compare(input, hash);
Étape 4 — A03 Injection (criticité : critique)
Vecteurs à couvrir :
- SQL (raw queries, ORM mal utilisés, stored procedures)
- NoSQL (MongoDB
$where, opérateurs injectés dans le body JSON)
- OS Command (
exec, shell_exec, subprocess)
- SSTI (templates Jinja2/Twig avec input utilisateur non échappé)
- XSS stocké/réfléchi/DOM
SQL injection — Python SQLAlchemy :
# ❌ Injection directe
query = f"SELECT * FROM users WHERE email = '{email}'"
# ✅ Paramétré
result = db.execute(text("SELECT * FROM users WHERE email = :e"), {"e": email})
Test NoSQL injection (MongoDB) :
# Tester un login — envoyer un objet au lieu d'une string
curl -X POST https://api.example.com/login \
-H "Content-Type: application/json" \
-d '{"username": {"$gt": ""}, "password": {"$gt": ""}}'
# Si 200 → injection confirmée
Étape 5 — A04 Insecure Design (criticité : haute)
Points de contrôle :
- Threat modeling réalisé sur les flux critiques (paiement, reset password, upload)
- Rate limiting présent sur login, SMS/email OTP, reset password
- Anti-automation (CAPTCHA, device fingerprint) sur les formulaires publics
- Failles logiques métier : contournement de prix, abus de promotions, skip d'étapes workflow
Rate limiting — Express (exemple) :
import rateLimit from 'express-rate-limit';
app.use('/auth/login', rateLimit({
windowMs: 15 * 60 * 1000, // 15 min
max: 10,
message: { error: 'Trop de tentatives, réessayez plus tard.' }
}));
Étape 6 — A05 à A10 (synthèse actionnable)
| ID |
Nom |
Vérifications prioritaires |
Outil/commande rapide |
| A05 |
Security Misconfiguration |
Headers de sécurité, comptes par défaut, stack trace exposée, permissions fichiers |
curl -I https://site.com ; securityheaders.com |
| A06 |
Vulnerable Components |
Dépendances avec CVE connues, packages abandonnés |
npm audit --audit-level=high / pip-audit / trivy fs . |
| A07 |
Auth Failures |
Brute force, credential stuffing, tokens prévisibles, session fixation, MFA absent |
Vérifier logs de tentatives échouées ; tester reset password flow |
| A08 |
Data Integrity Failures |
Désérialisation non sécurisée, vérification de signature des updates, CI/CD pipeline poisoning |
Éviter pickle.loads(user_data) ; vérifier checksums des assets |
| A09 |
Logging Failures |
Logs insuffisants sur auth/accès, absence d'alertes sur anomalies, PII dans les logs |
Vérifier que login fail / 403 / 500 sont logués avec contexte |
| A10 |
SSRF |
Validation stricte des URLs distantes, metadata cloud accessible, rebind DNS |
Tester http://169.254.169.254/latest/meta-data/ depuis un champ URL |
Headers de sécurité — configuration Nginx minimale :
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "DENY" always;
add_header Content-Security-Policy "default-src 'self'" always;
add_header Permissions-Policy "geolocation=(), microphone=()" always;
Audit dépendances NPM/Python :
npm audit --audit-level=high
pip-audit --requirement requirements.txt
trivy fs . --severity HIGH,CRITICAL
Étape 7 — Matrice de conformité
Produis un tableau récapitulatif :
| Catégorie |
Statut |
Criticité |
Effort remédiation |
| A01 Broken Access Control |
✅ Conforme |
— |
— |
| A02 Cryptographic Failures |
⚠️ Partiel |
Critique |
Moyen |
| A03 Injection |
❌ Non conforme |
Critique |
Faible |
| … |
… |
… |
… |
Score global : X/10 catégories conformes. Catégories bloquantes (critiques non conformes) à traiter avant mise en production.
Étape 8 — Plan de remédiation priorisé
Classe les actions selon la matrice Impact × Effort :
- Immédiat (< 1 semaine) : failles critiques exploitables (injection, IDOR, secrets exposés)
- Court terme (1–4 semaines) : misconfiguration, composants vulnérables, headers manquants
- Long terme (1–3 mois) : refonte design (rate limiting, threat modeling, logging structuré)
Pour chaque item : fournir l'extrait de code avant/après + la référence OWASP officielle (ex : A03:2021).
Garde-fous et anti-patterns
- Ne jamais fournir d'exploit fonctionnel sans mandat de pentest explicite — donner des PoC conceptuels uniquement
- Ne pas cocher "conforme" par défaut si l'information est insuffisante — signaler le manque d'info
- ORM ≠ immunité SQL : Hibernate, Prisma, SQLAlchemy peuvent être contournés avec
raw() ou text() mal utilisés
- HTTPS ≠ chiffrement complet : valider aussi le chiffrement au repos et dans les logs
- Dépendances transitives :
npm audit ne couvre pas toujours les sous-dépendances — utiliser trivy ou snyk
- A04 Insecure Design ne se corrige pas avec du code : nécessite une revue d'architecture
Bonnes pratiques 2026
- Utiliser OWASP ASVS (Application Security Verification Standard) pour un audit structuré par niveau (L1/L2/L3)
- Intégrer SAST (Semgrep, Sonarqube) et SCA (Trivy, Snyk) dans la CI pour détecter les régressions
- Adopter OpenID Connect / OAuth 2.1 pour l'authentification plutôt que les sessions custom
- Préférer Passkeys (WebAuthn) au mot de passe pour éliminer structurellement A07
- Pour les APIs, appliquer les vérifications OWASP API Security Top 10 2023 en complément
Communication Rules — MANDATORY
- Ultra-concise. No filler, no preamble, no pleasantries.
- Never say "happy to help", "sure!", "great question", "let me", or similar.
- Tool first, talk second. Act before explaining.
- Result first. Lead with outcome, not process.
- Stop when done. No summary, no recap, no trailing commentary.
- No politeness wrappers. Direct and blunt.
- Minimum words. If one word works, do not use ten.
- No unsolicited explanations.
- No emoji unless asked.
1---2name: dev-owasp-checker3description: Vérifie un projet contre le OWASP Top 10 (2021) et propose des remédiations concrètes avec exemples de code. À utiliser pour vérifier la conformité OWASP. Se déclenche avec "OWASP", "top 10", "failles web", "sécurité web", "A01 broken access", "injection", "vérifier OWASP". Also triggers on "OWASP Top 10 check", "web vulnerabilities", "is my app vulnerable".4---56# OWASP Checker78## Workflow910### Étape 1 — Cadrage initial11Avant d'auditer, demande (ou infère du contexte) :12- **Stack** : langage, framework, ORM, moteur de template13- **Type** : web MPA, SPA+API, API REST/GraphQL, microservices, mobile backend14- **Scope** : toute l'app ou un composant précis (auth, paiement, upload…)15- **Profondeur** : revue de code statique / checklist / test dynamique (pentest)1617Adapte les catégories à auditer : une API sans UI n'a pas de XSS stocké, un monolithe sans Docker n'a pas de misconfiguration container.1819---2021### Étape 2 — A01 Broken Access Control *(criticité : critique)*2223**Vérifications clés :**24- Chaque endpoint applique l'autorisation côté serveur (jamais côté client)25- Pas d'IDOR : les IDs en URL/paramètres sont vérifiés contre l'utilisateur courant26- Pas de force browsing : les routes protégées retournent 401/403, pas 20027- Séparation des rôles testée (admin, user, guest)2829**Exemple de faille IDOR — Node.js Express :**30```js31// ❌ Vulnérable32app.get('/orders/:id', auth, (req, res) => {33 db.query('SELECT * FROM orders WHERE id = ?', [req.params.id]);34});3536// ✅ Corrigé37app.get('/orders/:id', auth, (req, res) => {38 db.query('SELECT * FROM orders WHERE id = ? AND user_id = ?',39 [req.params.id, req.user.id]);40});41```4243**Commande de test rapide :**44```bash45# Tester l'accès cross-user avec curl46curl -H "Authorization: Bearer <token_user_A>" https://api.example.com/orders/4247# 42 appartient à user B → doit retourner 403, pas les données48```4950---5152### Étape 3 — A02 Cryptographic Failures *(criticité : critique)*5354**Checklist :**55- [ ] TLS 1.2+ obligatoire, TLS 1.0/1.1 désactivés (`testssl.sh` ou SSLLabs)56- [ ] Passwords : bcrypt (cost ≥ 12) ou Argon2id — jamais MD5/SHA1/SHA256 plain57- [ ] Secrets absents du code source (scan avec `trufflehog` ou `gitleaks`)58- [ ] Données sensibles absentes des logs, URLs, et réponses d'erreur5960**Scan de secrets dans git :**61```bash62# Installer gitleaks et scanner le repo complet63docker run -v $(pwd):/path zricethezav/gitleaks:latest detect --source /path --verbose64```6566**Hashing correct en Node.js :**67```js68import bcrypt from 'bcrypt';69// ✅ cost factor 12, résistant aux GPU70const hash = await bcrypt.hash(password, 12);71const ok = await bcrypt.compare(input, hash);72```7374---7576### Étape 4 — A03 Injection *(criticité : critique)*7778**Vecteurs à couvrir :**79- SQL (raw queries, ORM mal utilisés, stored procedures)80- NoSQL (MongoDB `$where`, opérateurs injectés dans le body JSON)81- OS Command (`exec`, `shell_exec`, `subprocess`)82- SSTI (templates Jinja2/Twig avec input utilisateur non échappé)83- XSS stocké/réfléchi/DOM8485**SQL injection — Python SQLAlchemy :**86```python87# ❌ Injection directe88query = f"SELECT * FROM users WHERE email = '{email}'"8990# ✅ Paramétré91result = db.execute(text("SELECT * FROM users WHERE email = :e"), {"e": email})92```9394**Test NoSQL injection (MongoDB) :**95```bash96# Tester un login — envoyer un objet au lieu d'une string97curl -X POST https://api.example.com/login \98 -H "Content-Type: application/json" \99 -d '{"username": {"$gt": ""}, "password": {"$gt": ""}}'100# Si 200 → injection confirmée101```102103---104105### Étape 5 — A04 Insecure Design *(criticité : haute)*106107**Points de contrôle :**108- Threat modeling réalisé sur les flux critiques (paiement, reset password, upload)109- Rate limiting présent sur login, SMS/email OTP, reset password110- Anti-automation (CAPTCHA, device fingerprint) sur les formulaires publics111- Failles logiques métier : contournement de prix, abus de promotions, skip d'étapes workflow112113**Rate limiting — Express (exemple) :**114```js115import rateLimit from 'express-rate-limit';116app.use('/auth/login', rateLimit({117 windowMs: 15 * 60 * 1000, // 15 min118 max: 10,119 message: { error: 'Trop de tentatives, réessayez plus tard.' }120}));121```122123---124125### Étape 6 — A05 à A10 (synthèse actionnable)126127| ID | Nom | Vérifications prioritaires | Outil/commande rapide |128|----|-----|---------------------------|-----------------------|129| A05 | Security Misconfiguration | Headers de sécurité, comptes par défaut, stack trace exposée, permissions fichiers | `curl -I https://site.com` ; `securityheaders.com` |130| A06 | Vulnerable Components | Dépendances avec CVE connues, packages abandonnés | `npm audit --audit-level=high` / `pip-audit` / `trivy fs .` |131| A07 | Auth Failures | Brute force, credential stuffing, tokens prévisibles, session fixation, MFA absent | Vérifier logs de tentatives échouées ; tester reset password flow |132| A08 | Data Integrity Failures | Désérialisation non sécurisée, vérification de signature des updates, CI/CD pipeline poisoning | Éviter `pickle.loads(user_data)` ; vérifier checksums des assets |133| A09 | Logging Failures | Logs insuffisants sur auth/accès, absence d'alertes sur anomalies, PII dans les logs | Vérifier que login fail / 403 / 500 sont logués avec contexte |134| A10 | SSRF | Validation stricte des URLs distantes, metadata cloud accessible, rebind DNS | Tester `http://169.254.169.254/latest/meta-data/` depuis un champ URL |135136**Headers de sécurité — configuration Nginx minimale :**137```nginx138add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;139add_header X-Content-Type-Options "nosniff" always;140add_header X-Frame-Options "DENY" always;141add_header Content-Security-Policy "default-src 'self'" always;142add_header Permissions-Policy "geolocation=(), microphone=()" always;143```144145**Audit dépendances NPM/Python :**146```bash147npm audit --audit-level=high148pip-audit --requirement requirements.txt149trivy fs . --severity HIGH,CRITICAL150```151152---153154### Étape 7 — Matrice de conformité155156Produis un tableau récapitulatif :157158| Catégorie | Statut | Criticité | Effort remédiation |159|-----------|--------|-----------|-------------------|160| A01 Broken Access Control | ✅ Conforme | — | — |161| A02 Cryptographic Failures | ⚠️ Partiel | Critique | Moyen |162| A03 Injection | ❌ Non conforme | Critique | Faible |163| … | … | … | … |164165**Score global** : X/10 catégories conformes. Catégories bloquantes (critiques non conformes) à traiter avant mise en production.166167---168169### Étape 8 — Plan de remédiation priorisé170171Classe les actions selon la matrice **Impact × Effort** :1721731. **Immédiat (< 1 semaine)** : failles critiques exploitables (injection, IDOR, secrets exposés)1742. **Court terme (1–4 semaines)** : misconfiguration, composants vulnérables, headers manquants1753. **Long terme (1–3 mois)** : refonte design (rate limiting, threat modeling, logging structuré)176177Pour chaque item : fournir l'extrait de code avant/après + la référence OWASP officielle (ex : [A03:2021](https://owasp.org/Top10/A03_2021-Injection/)).178179---180181## Garde-fous et anti-patterns182183- **Ne jamais fournir d'exploit fonctionnel** sans mandat de pentest explicite — donner des PoC conceptuels uniquement184- **Ne pas cocher "conforme" par défaut** si l'information est insuffisante — signaler le manque d'info185- **ORM ≠ immunité SQL** : Hibernate, Prisma, SQLAlchemy peuvent être contournés avec `raw()` ou `text()` mal utilisés186- **HTTPS ≠ chiffrement complet** : valider aussi le chiffrement au repos et dans les logs187- **Dépendances transitives** : `npm audit` ne couvre pas toujours les sous-dépendances — utiliser `trivy` ou `snyk`188- **A04 Insecure Design** ne se corrige pas avec du code : nécessite une revue d'architecture189190## Bonnes pratiques 2026191192- Utiliser **OWASP ASVS** (Application Security Verification Standard) pour un audit structuré par niveau (L1/L2/L3)193- Intégrer **SAST** (Semgrep, Sonarqube) et **SCA** (Trivy, Snyk) dans la CI pour détecter les régressions194- Adopter **OpenID Connect / OAuth 2.1** pour l'authentification plutôt que les sessions custom195- Préférer **Passkeys (WebAuthn)** au mot de passe pour éliminer structurellement A07196- Pour les APIs, appliquer les vérifications **OWASP API Security Top 10 2023** en complément197198199## Communication Rules — MANDATORY200201- Ultra-concise. No filler, no preamble, no pleasantries.202- Never say "happy to help", "sure!", "great question", "let me", or similar.203- Tool first, talk second. Act before explaining.204- Result first. Lead with outcome, not process.205- Stop when done. No summary, no recap, no trailing commentary.206- No politeness wrappers. Direct and blunt.207- Minimum words. If one word works, do not use ten.208- No unsolicited explanations.209- No emoji unless asked.