<!-- Matériel de référence basé sur la série OWASP Cheat Sheet (CC BY-SA 4.0) https://cheatsheetseries.owasp.org/ -->
Compétence en Audit de Sécurité
Identifier les vulnérabilités de sécurité exploitables dans le code. Signaler uniquement les résultats avec CONFIANCE ÉLEVÉE—des modèles vulnérables clairs avec des entrées contrôlées par l'attaquant.
Portée : Recherche vs. Signalement
DISTINCTION CRITIQUE :
- Signaler : Uniquement le fichier spécifique, diff ou code fourni par l'utilisateur
- Rechercher : L'ENSEMBLE de la base de code pour acquérir de la confiance avant de signaler
Avant de signaler un problème, vous DEVEZ rechercher dans la base de code pour comprendre :
- D'où vient réellement cette entrée ? (Tracer le flux de données)
- Y a-t-il une validation/sanitisation ailleurs ?
- Comment cela est-il configuré ? (Vérifier les paramètres, fichiers de config, middleware)
- Quelles protections du framework existent ?
NE PAS signaler les problèmes basés uniquement sur la correspondance de motifs. Enquêter d'abord, puis signaler uniquement ce dont vous êtes certain que c'est exploitable.
Niveaux de Confiance
| Niveau | Critères | Action |
|---|---|---|
| ÉLEVÉE | Motif vulnérable + entrée contrôlée par l'attaquant confirmée | Signaler avec sévérité |
| MOYENNE | Motif vulnérable, source d'entrée peu claire | Noter comme « Nécessite vérification » |
| BASSE | Théorique, bonne pratique, défense en profondeur | Ne pas signaler |
Ne Pas Signaler
Règles Générales
- Fichiers de test (sauf examen explicite de la sécurité des tests)
- Code mort, code commenté, chaînes de documentation
- Motifs utilisant des constantes ou une configuration contrôlée par le serveur
- Chemins de code nécessitant une authentification préalable pour être atteints (noter plutôt l'exigence d'auth)
Valeurs Contrôlées par le Serveur (NON Contrôlées par l'Attaquant)
Celles-ci sont configurées par les opérateurs, non contrôlées par les attaquants :
| Source | Exemple | Pourquoi C'est Sûr |
|---|---|---|
| Django settings | settings.API_URL, settings.ALLOWED_HOSTS |
Défini via config/env au déploiement |
| Variables d'environnement | os.environ.get('DATABASE_URL') |
Configuration du déploiement |
| Fichiers de config | config.yaml, app.config['KEY'] |
Fichiers côté serveur |
| Constantes du framework | django.conf.settings.* |
Non modifiable par l'utilisateur |
| Valeurs en dur | BASE_URL = "https://api.internal" |
Constantes au moment de la compilation |
Exemple SSRF - PAS une vulnérabilité :
# SÛR : L'URL provient de Django settings (contrôlée par le serveur)
response = requests.get(f"{settings.SEER_AUTOFIX_URL}{path}")
Exemple SSRF - EST une vulnérabilité :
# VULNÉRABLE : L'URL provient de la requête (contrôlée par l'attaquant)
response = requests.get(request.GET.get('url'))
Motifs Atténués par le Framework
Vérifier les guides de langue avant de signaler. Faux positifs courants :
| Motif | Pourquoi C'est Généralement Sûr |
|---|---|
Django {{ variable }} |
Auto-échappé par défaut |
React {variable} |
Auto-échappé par défaut |
Vue {{ variable }} |
Auto-échappé par défaut |
User.objects.filter(id=input) |
ORM paramétre les requêtes |
cursor.execute("...%s", (input,)) |
Requête paramétrée |
innerHTML = "<b>Loading...</b>" |
Chaîne constante, pas d'entrée utilisateur |
Signaler uniquement quand :
- Django :
{{ var|safe }},{% autoescape off %},mark_safe(user_input) - React :
dangerouslySetInnerHTML={{__html: userInput}} - Vue :
v-html="userInput" - ORM :
.raw(),.extra(),RawSQL()avec interpolation de chaîne
Processus d'Audit
1. Détecter le Contexte
Quel type de code suis-je en train d'examiner ?
| Type de Code | Charger Ces Références |
|---|---|
| Points de terminaison API, routes | authorization.md, authentication.md, injection.md |
| Frontend, modèles | xss.md, csrf.md |
| Gestion de fichiers, uploads | file-security.md |
| Crypto, secrets, tokens | cryptography.md, data-protection.md |
| Sérialisation de données | deserialization.md |
| Requêtes externes | ssrf.md |
| Flux métier | business-logic.md |
| GraphQL, conception REST | api-security.md |
| Config, en-têtes, CORS | misconfiguration.md |
| CI/CD, dépendances | supply-chain.md |
| Gestion des erreurs | error-handling.md |
| Audit, journalisation | logging.md |
2. Charger le Guide de Langue
Basé sur l'extension de fichier ou les imports :
| Indicateurs | Guide |
|---|---|
.py, django, flask, fastapi |
languages/python.md |
.js, .ts, express, react, vue, next |
languages/javascript.md |
.go, go.mod |
languages/go.md |
.rs, Cargo.toml |
languages/rust.md |
.java, spring, @Controller |
languages/java.md |
3. Charger le Guide d'Infrastructure (si applicable)
| Type de Fichier | Guide |
|---|---|
Dockerfile, .dockerignore |
infrastructure/docker.md |
| Manifestes K8s, graphiques Helm | infrastructure/kubernetes.md |
.tf, Terraform |
infrastructure/terraform.md |
GitHub Actions, .gitlab-ci.yml |
infrastructure/ci-cd.md |
| Configs AWS/GCP/Azure, IAM | infrastructure/cloud.md |
4. Rechercher Avant de Signaler
Pour chaque problème potentiel, rechercher dans la base de code pour acquérir de la confiance :
- D'où vient réellement cette valeur ? Tracer le flux de données.
- Est-elle configurée au déploiement (paramètres, variables env) ou provient-elle d'une entrée utilisateur ?
- Y a-t-il une validation, une sanitisation ou une liste blanche ailleurs ?
- Quelles protections du framework s'appliquent ?
Signaler uniquement les problèmes dont vous êtes SÛR après avoir compris le contexte plus large.
5. Vérifier l'Exploitabilité
Pour chaque résultat potentiel, confirmer :
L'entrée est-elle contrôlée par l'attaquant ?
| Contrôlée par l'Attaquant (Enquêter) | Contrôlée par le Serveur (Généralement Sûr) |
|---|---|
request.GET, request.POST, request.args |
settings.X, app.config['X'] |
request.json, request.data, request.body |
os.environ.get('X') |
request.headers (la plupart des en-têtes) |
Constantes en dur |
request.cookies (non signées) |
URLs de services internes depuis la config |
Segments de chemin URL : /users/<id>/ |
Contenu de la base de données depuis l'admin/système |
| Uploads de fichiers (contenu et noms) | Données de session signées |
| Contenu de la base de données d'autres utilisateurs | Paramètres du framework |
| Messages WebSocket |
Le framework atténue-t-il cela ?
- Vérifier le guide de langue pour l'auto-échappement, la paramétrisation
- Vérifier les middleware/décorateurs qui sanitisent
Y a-t-il une validation en amont ?
- Validation d'entrée avant ce code
- Bibliothèques de sanitisation (DOMPurify, bleach, etc.)
6. Signaler Uniquement la Confiance Élevée
Ignorer les problèmes théoriques. Signaler uniquement ce dont vous avez confirmé l'exploitabilité après recherche.
Classification de Sévérité
| Sévérité | Impact | Exemples |
|---|---|---|
| Critique | Exploitation directe, impact grave, pas d'auth requise | RCE, injection SQL sur données, contournement d'auth, secrets codés en dur |
| Élevée | Exploitable avec conditions, impact significatif | XSS stocké, SSRF vers métadonnées, IDOR sur données sensibles |
| Moyenne | Conditions spécifiques requises, impact modéré | XSS réfléchi, CSRF sur actions changeant l'état, traversée de répertoire |
| Basse | Défense en profondeur, impact direct minimal | En-têtes manquants, erreurs verboses, algorithmes faibles dans contexte non critique |
Référence Rapide de Motifs
Toujours Signaler (Critique)
eval(user_input) # N'importe quel langage
exec(user_input) # N'importe quel langage
pickle.loads(user_data) # Python
yaml.load(user_data) # Python (pas safe_load)
unserialize($user_data) # PHP
deserialize(user_data) # Java ObjectInputStream
shell=True + user_input # Python subprocess
child_process.exec(user) # Node.js
Toujours Signaler (Élevé)
innerHTML = userInput # DOM XSS
dangerouslySetInnerHTML={user} # React XSS
v-html="userInput" # Vue XSS
f"SELECT * FROM x WHERE {user}" # Injection SQL
`SELECT * FROM x WHERE ${user}` # Injection SQL
os.system(f"cmd {user_input}") # Injection de commande
Toujours Signaler (Secrets)
password = "hardcoded"
api_key = "sk-..."
AWS_SECRET_ACCESS_KEY = "..."
private_key = "-----BEGIN"
Vérifier le Contexte D'abord (DOIT Enquêter Avant de Signaler)
# SSRF - UNIQUEMENT si l'URL provient d'une entrée utilisateur, PAS de settings/config
requests.get(request.GET['url']) # SIGNALER : URL contrôlée par l'utilisateur
requests.get(settings.API_URL) # SÛR : Config contrôlée par le serveur
requests.get(f"{settings.BASE}/{x}") # VÉRIFIER : 'x' est-il une entrée utilisateur ?
# Traversée de répertoire - UNIQUEMENT si le chemin provient d'une entrée utilisateur
open(request.GET['file']) # SIGNALER : Chemin contrôlé par l'utilisateur
open(settings.LOG_PATH) # SÛR : Config contrôlée par le serveur
open(f"{BASE_DIR}/{filename}") # VÉRIFIER : 'filename' est-il une entrée utilisateur ?
# Redirection ouverte - UNIQUEMENT si l'URL provient d'une entrée utilisateur
redirect(request.GET['next']) # SIGNALER : Redirection contrôlée par l'utilisateur
redirect(settings.LOGIN_URL) # SÛR : Config contrôlée par le serveur
# Crypto faible - UNIQUEMENT si utilisé à des fins de sécurité
hashlib.md5(file_content) # SÛR : Checksums de fichiers, cache
hashlib.md5(password) # SIGNALER : Hachage de mot de passe
random.random() # SÛR : Usages non-sécurité (UI, échantillonnage)
random.random() for token # SIGNALER : Les tokens de sécurité ont besoin du module secrets
Format de Sortie
## Audit de Sécurité : [Nom du Fichier/Composant]
### Résumé
- **Résultats** : X (Y Critique, Z Élevée, ...)
- **Niveau de Risque** : Critique/Élevé/Moyen/Bas
- **Confiance** : Élevée/Mixte
### Résultats
#### [VULN-001] [Type de Vulnérabilité] (Sévérité)
- **Localisation** : `file.py:123`
- **Confiance** : Élevée
- **Problème** : [Ce qu'est la vulnérabilité]
- **Impact** : [Ce qu'un attaquant pourrait faire]
- **Preuve** :
```python
[Extrait de code vulnérable]
- Correction : [Comment remédier]
Nécessite Vérification
[VERIFY-001] [Problème Potentiel]
- Localisation :
file.py:456 - Question : [Ce qui doit être vérifié]
Si aucune vulnérabilité n'est trouvée, indiquer : « Aucune vulnérabilité de confiance élevée identifiée. »
Fichiers de Référence
Vulnérabilités Principales (references/)
| Fichier | Couvre |
|---|---|
injection.md |
SQL, NoSQL, commande OS, LDAP, injection de modèle |
xss.md |
XSS réfléchi, stocké, basé sur DOM |
authorization.md |
Autorisation, IDOR, escalade de privilèges |
authentication.md |
Sessions, identifiants, stockage de mot de passe |
cryptography.md |
Algorithmes, gestion des clés, aléa |
deserialization.md |
Pickle, YAML, Java, désérialisation PHP |
file-security.md |
Traversée de répertoire, uploads, XXE |
ssrf.md |
Forgerie de requête côté serveur |
csrf.md |
Contrefaçon de requête intersites |
data-protection.md |
Exposition de secrets, PII, journalisation |
api-security.md |
REST, GraphQL, affectation de masse |
business-logic.md |
Conditions de course, contournement de flux |
modern-threats.md |
Prototype pollution, injection LLM, WebSocket |
misconfiguration.md |
En-têtes, CORS, mode debug, défauts |
error-handling.md |
Fail-open, divulgation d'information |
supply-chain.md |
Dépendances, sécurité de la build |
logging.md |
Échecs d'audit, injection de journal |
Guides de Langue (languages/)
python.md- Motifs Django, Flask, FastAPIjavascript.md- Node, Express, React, Vue, Next.jsgo.md- Motifs de sécurité spécifiques à Gorust.md- Blocs unsafe Rust, sécurité FFIjava.md- Motifs Spring, Java EE
Infrastructure (infrastructure/)
docker.md- Sécurité des conteneurskubernetes.md- K8s RBAC, secrets, politiquesterraform.md- Sécurité IaCci-cd.md- Sécurité du pipelinecloud.md- Sécurité AWS/GCP/Azure