security-review

Revue de sécurité du code pour détecter les vulnérabilités. À utiliser lorsqu'on vous demande d'effectuer une « security review », de « trouver des vulnérabilités », de « vérifier les problèmes de sécurité », d'« auditer la sécurité », d'effectuer une « revue OWASP », ou d'analyser du code pour des problèmes d'injection, XSS, d'authentification, d'autorisation ou de cryptographie. Fournit une revue systématique avec un rapport basé sur la confiance.

npx skills add https://github.com/getsentry/skills --skill security-review

<!-- Matériel de référence basé sur OWASP Cheat Sheet Series (CC BY-SA 4.0) https://cheatsheetseries.owasp.org/ -->

Compétence d'Audit de Sécurité

Identifier les vulnérabilités de sécurité exploitables dans le code. Signaler uniquement les résultats de CONFIANCE ÉLEVÉE—modèles vulnérables clairs avec entrée contrôlée par un attaquant.

Périmètre : Recherche vs. Signalement

DISTINCTION CRITIQUE :

  • Signaler : Uniquement le fichier spécifique, diff ou code fourni par l'utilisateur
  • Rechercher : L'INTÉGRALITÉ de la base de code pour générer de la confiance avant de signaler

Avant de signaler un problème, vous DEVEZ explorer la base de code pour comprendre :

  • D'où provient réellement cette entrée ? (Tracer le flux de données)
  • Y a-t-il une validation/assainissement ailleurs ?
  • Comment cela est-il configuré ? (Vérifier les paramètres, fichiers de config, middleware)
  • Quelles protections du framework existent ?

Ne signalez PAS les problèmes basés uniquement sur la reconnaissance de motifs. Enquêtez d'abord, puis signalez seulement ce dont vous êtes confiant quant à l'exploitabilité.

Niveaux de Confiance

Niveau Critères Action
ÉLEVÉE Modèle vulnérable + entrée contrôlée par attaquant confirmée Signaler avec sévérité
MOYENNE Modèle vulnérable, source d'entrée peu claire Noter comme « Nécessite vérification »
FAIBLE 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
  • Modèles utilisant des constantes ou une configuration contrôlée par le serveur
  • Chemins de code nécessitant une authentification préalable pour y accéder (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
Paramètres Django settings.API_URL, settings.ALLOWED_HOSTS Défini via config/env au déploiement
Variables d'environnement os.environ.get('DATABASE_URL') Configuration de déploiement
Fichiers de config config.yaml, app.config['KEY'] Fichiers côté serveur
Constantes du framework django.conf.settings.* Non modifiables par l'utilisateur
Valeurs codées en dur BASE_URL = "https://api.internal" Constantes au moment de la compilation

Exemple SSRF - N'EST PAS une vulnérabilité :

# SÛR : L'URL provient des paramètres Django (contrôlée par 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 attaquant)
response = requests.get(request.GET.get('url'))

Modèles Atténués par le Framework

Consultez les guides linguistiques avant de signaler. Les faux positifs courants :

Modèle 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) L'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

Signalez ces cas 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 j'examine ?

Type de Code Charger Ces Références
Points d'accès API, routes authorization.md, authentication.md, injection.md
Frontend, modèles xss.md, csrf.md
Gestion des fichiers, uploads file-security.md
Crypto, secrets, tokens cryptography.md, data-protection.md
Sérialisation des 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 Linguistique

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 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, explorez la base de code pour générer de la confiance :

  • D'où provient réellement cette valeur ? Tracer le flux de données.
  • Est-elle configurée au déploiement (paramètres, variables d'env) ou provient-elle d'une entrée utilisateur ?
  • Y a-t-il une validation, un assainissement ou une liste d'autorisation ailleurs ?
  • Quelles protections du framework s'appliquent ?

Signalez uniquement les problèmes dont vous êtes certain à CONFIANCE ÉLEVÉE après avoir compris le contexte plus large.

5. Vérifier l'Exploitabilité

Pour chaque résultat potentiel, confirmez :

L'entrée est-elle contrôlée par l'attaquant ?

Contrôlée par Attaquant (À Enquêter) Contrôlée par 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 codées en dur
request.cookies (non signés) URLs de service interne depuis config
Segments de chemin URL : /users/<id>/ Contenu de base de données depuis admin/système
Uploads de fichiers (contenu et noms) Données de session signées
Contenu de base de données d'autres utilisateurs Paramètres du framework
Messages WebSocket

Le framework atténue-t-il cela ?

  • Vérifier le guide linguistique pour l'auto-échappement, la paramétrisation
  • Vérifier les middleware/décorateurs qui assainissent

Y a-t-il une validation en amont ?

  • Validation d'entrée avant ce code
  • Bibliothèques d'assainissement (DOMPurify, bleach, etc.)

6. Signaler Uniquement à Confiance Élevée

Ignorer les problèmes théoriques. Signaler seulement ce que vous avez confirmé être exploitable après recherche.


Classification de la Sévérité

Sévérité Impact Exemples
Critique Exploit direct, impact grave, pas d'auth requise RCE, SQL injection sur données, contournement d'auth, secrets codés en dur
Élevée Exploitable sous 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
Faible Défense en profondeur, impact direct minimal En-têtes manquants, erreurs verboses, algorithmes faibles en contexte non critique

Référence Rapide des Modèles

Toujours Signaler (Critique)

eval(user_input)           # Tout langage
exec(user_input)           # Tout 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ée)

innerHTML = userInput              # DOM XSS
dangerouslySetInnerHTML={user}     # React XSS
v-html="userInput"                 # Vue XSS
f"SELECT * FROM x WHERE {user}"    # SQL injection
`SELECT * FROM x WHERE ${user}`    # SQL injection
os.system(f"cmd {user_input}")     # Command injection

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 - SEULEMENT si l'URL provient d'entrée utilisateur, PAS de settings/config
requests.get(request.GET['url'])     # SIGNALER : URL contrôlée par utilisateur
requests.get(settings.API_URL)       # SÛR : Config contrôlée par serveur
requests.get(f"{settings.BASE}/{x}") # VÉRIFIER : 'x' est-il entrée utilisateur ?

# Path traversal - SEULEMENT si le chemin provient d'entrée utilisateur
open(request.GET['file'])            # SIGNALER : Chemin contrôlé par utilisateur
open(settings.LOG_PATH)              # SÛR : Config contrôlée par serveur
open(f"{BASE_DIR}/{filename}")       # VÉRIFIER : 'filename' est-il entrée utilisateur ?

# Open redirect - SEULEMENT si l'URL provient d'entrée utilisateur
redirect(request.GET['next'])        # SIGNALER : Redirection contrôlée par utilisateur
redirect(settings.LOGIN_URL)         # SÛR : Config contrôlée par serveur

# Crypto faible - SEULEMENT si utilisé pour la sécurité
hashlib.md5(file_content)            # SÛR : Sommes de contrôle de fichiers, cache
hashlib.md5(password)                # SIGNALER : Hachage de mot de passe
random.random()                      # SÛR : Usages non-sécurité (UI, sampling)
random.random() pour token           # SIGNALER : Les tokens de sécurité nécessitent secrets module

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/Faible
- **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, déclarez : « Aucune vulnérabilité à 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ège
authentication.md Sessions, credentials, stockage de mot de passe
cryptography.md Algorithmes, gestion de clés, aléatoire
deserialization.md Pickle, YAML, Java, PHP deserialization
file-security.md Traversée de répertoire, uploads, XXE
ssrf.md Server-side request forgery
csrf.md Cross-site request forgery
data-protection.md Exposition de secrets, PII, journalisation
api-security.md REST, GraphQL, assignation 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, defaults
error-handling.md Fail-open, divulgation d'information
supply-chain.md Dépendances, sécurité de build
logging.md Échecs d'audit, injection de log

Guides Linguistiques (languages/)

  • python.md - Modèles Django, Flask, FastAPI
  • javascript.md - Node, Express, React, Vue, Next.js
  • go.md - Modèles de sécurité spécifiques à Go
  • rust.md - Blocs unsafe Rust, sécurité FFI
  • java.md - Modèles Spring, Java EE

Infrastructure (infrastructure/)

  • docker.md - Sécurité des conteneurs
  • kubernetes.md - K8s RBAC, secrets, policies
  • terraform.md - Sécurité IaC
  • ci-cd.md - Sécurité du pipeline
  • cloud.md - Sécurité AWS/GCP/Azure

Skills similaires