Mode d’emploi Cochez chaque point vérifié en production , pas seulement dans le code : un auditeur teste ce qui est exposé. Votre progression reste enregistrée dans ce navigateur, rien n’est envoyé.
Traitez d’abord les points Critique . Viennent ensuite les points Haute , attendus par tout auditeur sérieux, puis les points Reco , qui relèvent de la défense en profondeur.
01 · A02 · Security Misconfiguration
En-têtes HTTP de sécurité 0 / 13
Premier point contrôlé par tout auditeur : 30 secondes avec securityheaders.com ou Mozilla Observatory.
Strict-Transport-Security Critique max-age=63072000; includeSubDomains; preload. Puis inscription sur hstspreload.org. Content-Security-Policy stricte Critique Nonces ou hashes + 'strict-dynamic', object-src 'none', base-uri 'none'. Interdits : 'unsafe-inline', 'unsafe-eval', *. CSP déployée d'abord en Report-Only Haute Content-Security-Policy-Report-Only + report-to pendant 1 à 2 semaines avant de passer en mode bloquant. Anti-clickjacking Critique frame-ancestors 'none' dans la CSP + X-Frame-Options: DENY pour les vieux navigateurs. X-Content-Type-Options Haute nosniff sur toutes les réponses, y compris les assets et l'API. Referrer-Policy Haute strict-origin-when-cross-origin (ou no-referrer sur les pages sensibles). Permissions-Policy Haute Couper ce qui ne sert pas : camera=(), microphone=(), geolocation=(), payment=(), usb=(). Isolation cross-origin Reco Cross-Origin-Opener-Policy: same-origin et Cross-Origin-Resource-Policy: same-origin. COEP: require-corp seulement si besoin. X-XSS-Protection retiré Haute Header obsolète : mettre 0 ou le supprimer (l'ancien filtre XSS a lui-même causé des failles). Fuite de versions Haute Supprimer Server, X-Powered-By, X-AspNet-Version, ainsi que les versions dans les pages d'erreur. Cache des pages authentifiées Haute Cache-Control: no-store sur les pages et réponses API contenant des données personnelles. Déconnexion propre Reco Clear-Site-Data: "cache", "cookies", "storage" sur l'endpoint de logout. Reporting Reco Reporting-Endpoints configuré pour collecter les violations CSP et les erreurs réseau. 02 · A04 · Cryptographic Failures
HTTPS & TLS 0 / 7
Objectif : note A+ sur SSL Labs, testssl.sh sans alerte rouge.
03 · Usurpation · Phishing · Takeover
DNS, domaine & e-mail 0 / 14
Le DNS est souvent oublié des devs, mais jamais des auditeurs ni des attaquants.
Verrou registrar + 2FA Critique clientTransferProhibited actif, 2FA sur le compte registrar, renouvellement auto, contacts à jour. DNSSEC activé Haute Zone signée, enregistrement DS publié chez le registrar. Vérifiable sur dnsviz.net. Enregistrement CAA Haute 0 issue "letsencrypt.org" (uniquement vos CA) + 0 iodef "mailto:security@…". Pas de sous-domaine orphelin Critique Aucun CNAME pointant vers une ressource supprimée (Netlify, Vercel, S3, Heroku, GitHub Pages). Risque : subdomain takeover. SPF strict Critique Un seul enregistrement, au plus 10 lookups DNS, se terminant par -all (pas ~all ni +all). DKIM Critique Clés ≥ 2048 bits pour chaque service d'envoi (Google, Sweego, Brevo…), avec rotation. DMARC en p=reject Critique v=DMARC1; p=reject; rua=mailto:…; adkim=s; aspf=s. Progression : none, puis quarantine, puis reject. MTA-STS + TLS-RPT Haute Impose le TLS aux serveurs qui vous envoient du mail et fournit les rapports d'échec. Domaines qui n'envoient pas de mail Haute v=spf1 -all, DMARC p=reject, MX nul 0 ., pour empêcher leur usurpation. Transfert de zone fermé Haute AXFR refusé depuis l'extérieur (dig axfr @ns domaine doit échouer). Résilience DNS Reco Au moins 2 serveurs NS, idéalement chez 2 fournisseurs. TTL cohérents. IP d'origine masquée Reco Le serveur d'origine n'accepte que le trafic du CDN/WAF. Pas de fuite via un vieil A record ou un en-tête d'e-mail. Typosquatting Reco Surveillance des domaines proches (dnstwist) et rachat des variantes critiques. security.txt Reco /.well-known/security.txt avec Contact, Expires et Policy (RFC 9116). 04 · A05 · Injection
Failles XSS 0 / 9
Cible n°1 des pentesteurs web. Chaque point d'entrée utilisateur est testé.
Échappement contextuel en sortie Critique Corps HTML, attribut, JS, URL et CSS ont chacun leur échappement. S'appuyer sur l'auto-escape du framework. Aucun HTML brut non assaini Critique Bannir innerHTML, dangerouslySetInnerHTML, v-html, set:html et {@html} avec une donnée utilisateur, sauf passage par DOMPurify. Schémas d'URL filtrés Critique Bloquer javascript:, data: et vbscript: dans les href/src fournis par l'utilisateur. Liste blanche http(s)/mailto. XSS DOM Haute Pas de eval, new Function, setTimeout(string) ni document.write. Lectures de location.hash/search assainies. JSON dans un <script> Haute Échapper <, >, &, U+2028 et U+2029 lors de l'injection d'un état serveur dans la page. Trusted Types Haute require-trusted-types-for 'script' dans la CSP pour verrouiller les sinks DOM (Chromium). Markdown & rich text Haute Rendu côté serveur avec une liste blanche de balises et d'attributs. Les on*= et style sont retirés. SVG et fichiers uploadés Haute Pas de SVG utilisateur servi inline sur le domaine principal (il peut contenir du JS). Tests automatisés Reco Payloads de référence ("><svg onload=alert(1)>, polyglots) sur chaque champ, dans la CI ou via ZAP. 05 · A05 · Injection
Autres injections 0 / 9
Toute donnée externe est hostile : query, body, headers, cookies, fichiers, webhooks.
SQL injection Critique Requêtes paramétrées ou ORM partout. Aucune concaténation, y compris dans ORDER BY (liste blanche). NoSQL injection Critique Rejeter les opérateurs ($ne, $gt, $where) dans les entrées, typer strictement les champs. Injection de commande OS Critique Pas de exec/system avec une entrée utilisateur. Sinon execFile + arguments en tableau + liste blanche. SSTI Haute Jamais de template construit à partir d'une entrée utilisateur (Jinja, Twig, Handlebars, EJS…). Path traversal Haute Normaliser le chemin puis vérifier qu'il reste dans le dossier autorisé. Refuser ../ et %2e%2e. XXE Haute Entités externes et DTD désactivées dans tous les parseurs XML (SVG, DOCX et SAML inclus). CRLF / header injection Haute Retirer \r\n des valeurs placées dans les en-têtes, cookies, redirections et e-mails. Prototype pollution (JS) Haute Bloquer __proto__, constructor et prototype dans les merges profonds. Utiliser Object.create(null) ou Map. Open redirect Reco Paramètres ?next=/?redirect= limités à des chemins relatifs ou à une liste blanche de domaines. 06 · A07 · Authentication Failures
Cookies, sessions & CSRF 0 / 6
07 · A07 · Authentication Failures
Authentification 0 / 9
Hash des mots de passe Critique Argon2id (ou bcrypt coût ≥ 12, scrypt). Jamais MD5, SHA-1 ou SHA-256 seul. Anti brute-force Critique Rate limiting par IP et par compte, backoff progressif, CAPTCHA/Turnstile après N échecs. MFA Critique Obligatoire pour les admins, proposée à tous. Passkeys/WebAuthn ou TOTP plutôt que le SMS. Pas d'énumération de comptes Haute Message et temps de réponse identiques pour « compte inconnu » et « mauvais mot de passe », au login, au reset et à l'inscription. Reset de mot de passe Haute Token aléatoire ≥ 128 bits, à usage unique, expirant en 15-60 min, stocké hashé. Sessions invalidées après le reset. Politique de mot de passe Haute Minimum 12 caractères, refus des mots de passe compromis (API HIBP k-anonymity), pas de règles de composition absurdes. JWT Haute Algorithme épinglé côté serveur (refuser none et la confusion HS/RS), exp court, aud et iss vérifiés, refresh token rotatif. OAuth / OIDC Haute PKCE, paramètre state vérifié, redirect_uri en correspondance exacte, nonce contrôlé. Comptes par défaut Reco Aucun compte admin/admin ni identifiant de démo en production. 08 · A01 · Broken Access Control
Contrôle d'accès 0 / 7
Catégorie n°1 de l'OWASP Top 10, et la plus fréquente dans les rapports d'audit.
09 · A01 · A02 · A05
API, CORS & SSRF 0 / 9
CORS strict Critique Liste blanche explicite des origines. Jamais * avec credentials, jamais de reflet aveugle du header Origin. Validation des entrées par schéma Critique Zod, Joi ou JSON Schema sur chaque endpoint : types, longueurs, formats, champs inconnus rejetés. SSRF Critique Les URL fournies par l'utilisateur passent par une liste blanche. Blocage de 169.254.169.254, localhost, des IP privées et des redirections. IMDSv2 sur AWS. Rate limiting & quotas Haute Par IP, utilisateur et clé API, avec une réponse 429 + Retry-After. Taille des payloads Haute Limite sur le body, la pagination (limit max), les uploads et la profondeur JSON. Erreurs génériques Haute Aucune stack trace, requête SQL ou chemin serveur dans la réponse. Le détail reste dans les logs. GraphQL Haute Introspection coupée en prod, limites de profondeur et de complexité, batching limité. Webhooks entrants Haute Signature HMAC vérifiée, horodatage contrôlé (anti-replay), idempotence. Inventaire des endpoints Reco OpenAPI à jour, aucun endpoint « shadow » ni ancienne version /v1 oubliée. 10 · A05 · A06
Upload de fichiers 0 / 7
11 · A02 · Security Misconfiguration
Secrets & configuration 0 / 8
Aucun secret dans le code Critique gitleaks/trufflehog sur tout l'historique Git + hook pre-commit. Rotation de tout secret ayant fuité. Fichiers sensibles inaccessibles Critique /.env, /.git/, /backup.sql, /config.php.bak et /.DS_Store renvoient 404. Mode debug coupé Critique NODE_ENV=production, DEBUG=False. Pas de profiler, phpinfo ou console Werkzeug exposés. Secrets côté client Haute Seules les clés publiques sont dans le bundle front (PUBLIC_, NEXT_PUBLIC_, VITE_). Pas de service_role ni de clé secrète. Source maps Haute Non publiées en prod, ou réservées à Sentry. Listing de répertoires Haute Désactivé sur le serveur et sur les buckets. Gestion des secrets Haute Variables d'environnement de la plateforme ou coffre (AWS Secrets Manager, Doppler, 1Password). Rotation planifiée. Moindre privilège des clés Reco Une clé par service, avec des scopes minimaux et des restrictions IP/domaine (Google Maps, etc.). 12 · A03 · Software Supply Chain Failures
Dépendances & supply chain 0 / 8
13 · A02 · Security Misconfiguration
Infrastructure & cloud 0 / 10
Comptes cloud Critique MFA sur root/owner, root jamais utilisé au quotidien, IAM au moindre privilège, pas de clés d'accès longue durée. Bases de données privées Critique Aucune DB, Redis ou Elasticsearch exposé sur Internet. Security groups restreints, accès via bastion/VPN. Buckets Critique S3 Block Public Access activé au niveau du compte. Policies auditées. WAF & anti-DDoS Haute Cloudflare, AWS WAF ou équivalent, règles OWASP managées, rate limiting en bordure. Chiffrement au repos Haute Disques, DB, backups et buckets chiffrés (KMS). Patching Haute OS et runtimes à jour, mises à jour de sécurité automatiques, plan pour les CVE critiques sous 72 h. SSH Haute Clé uniquement, root login interdit, port fermé au public (SSM ou bastion). Sauvegardes 3-2-1 Haute Chiffrées, hors du compte principal, immuables. Restauration testée chaque trimestre. Ports ouverts Reco Scan externe (nmap, Shodan) : seuls 80 et 443 répondent. Environnements séparés Reco Prod, staging et dev isolés (comptes, données, secrets). Aucune donnée réelle hors prod. 14 · A09 · Logging & Alerting Failures
Logs, détection & réponse 0 / 7
Événements de sécurité journalisés Critique Logins (succès et échecs), changements de droits, resets, accès admin, erreurs 401/403 en masse. Pas de données sensibles dans les logs Critique Mots de passe, tokens, numéros de carte et données de santé masqués. Centralisation & alertes Haute Logs centralisés (CloudWatch, Datadog, Grafana Loki), alertes sur les anomalies, rétention ≥ 1 an pour la sécurité. Monitoring d'erreurs Haute Sentry ou équivalent, avec scrubbing des données personnelles. Gestion des erreurs Haute Les exceptions échouent en mode fermé (fail closed) et ne laissent pas d'état incohérent (A10). Plan de réponse à incident Haute Qui appeler, comment couper un accès, révoquer des clés, communiquer. Exercice annuel. Intégrité des logs Reco Logs en append-only, non modifiables par l'application. 15 · CNIL · RGPD
RGPD & conformité 0 / 7
A · Annexes
Config prête à copier En-têtes de sécurité : _headers (Netlify / Cloudflare Pages) Le nonce CSP doit être généré à chaque requête (middleware / edge function). Pour un site 100 % statique, utilisez des hashes 'sha256-…' à la place.
/*
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-{NONCE}' 'strict-dynamic'; style-src 'self' https://fonts.googleapis.com; font-src https://fonts.gstatic.com; img-src 'self' data:; connect-src 'self'; object-src 'none'; base-uri 'none'; frame-ancestors 'none'; form-action 'self'; upgrade-insecure-requests
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=(), usb=()
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Resource-Policy: same-origin Enregistrements DNS de référence example.fr. CAA 0 issue "letsencrypt.org"
example.fr. CAA 0 iodef "mailto:security@example.fr"
example.fr. TXT "v=spf1 include:_spf.google.com -all"
_dmarc.example.fr. TXT "v=DMARC1; p=reject; rua=mailto:dmarc@example.fr; adkim=s; aspf=s"
_mta-sts.example.fr TXT "v=STSv1; id=20261003"
_smtp._tls TXT "v=TLSRPTv1; rua=mailto:tlsrpt@example.fr"
# domaine qui n'envoie aucun mail
parked.fr. MX 0 .
parked.fr. TXT "v=spf1 -all" Vérifications rapides en ligne de commande # En-têtes
curl -sI https://example.fr | grep -iE 'strict|content-security|x-frame|x-content|referrer|permissions'
# TLS
testssl.sh --severity MEDIUM example.fr
# DNS & mail
dig +short CAA example.fr ; dig +short TXT _dmarc.example.fr ; dig +dnssec example.fr
# Fichiers exposés
for p in .env .git/HEAD .DS_Store backup.sql; do curl -so /dev/null -w "%{http_code} $p\n" https://example.fr/$p; done
# Secrets & dépendances
gitleaks detect --source . ; pnpm audit --audit-level high Boîte à outils de l’auditeur Les outils que les auditeurs lancent en premier. Passez-les vous-même avant eux.
Besoin d’un pré-audit ? Coffee Beans passe votre application au crible de cette checklist et corrige les points bloquants avant l’audit officiel.