DNS RobotDNS Propagation Checker
AccueilDNSWHOISIPSSL
DNS RobotDNS Propagation Checker

Boîte à outils DNS nouvelle génération

Politique de ConfidentialitéConditions d'UtilisationÀ ProposBlogContact

Outils DNS

Recherche DNSTest de Vitesse DNSDomaine vers IPRecherche NSRecherche MXVoir tout

Outils E-mail

Vérificateur d'Enregistrement SPFVérificateur DMARCVérificateur DKIMOutil de Test SMTPAnalyseur d'En-têtes E-mailVoir tout

Outils Web

Recherche WHOISVérificateur d'hébergementDisponibilité de DomaineRecherche de Sous-domainesDétecteur de CMSVoir tout

Outils Réseau

Outil PingTracerouteVérificateur de PortsVérification des En-têtes HTTPVérification du Certificat SSLVoir tout

Outils IP

Recherche IPQuelle Est Mon IPVérification de Liste Noire IPIP vers HostnameRecherche ASNVoir tout

Outils Utilitaires

Scanner de QR CodeGénérateur de QR CodeUPI QR Code GeneratorWiFi QR Code GeneratorTraducteur de Code MorseVoir tout
© 2026 DNS Robot. Développé par : ❤ Shaik Brothers
Tous les systèmes opérationnels
Made with
Accueil/Blog/Sécurité web : bonnes pratiques couche par couche (2026)

Sécurité web : bonnes pratiques couche par couche (2026)

Shaik Vahid29 sept. 202630 min de lecture
Sécurité web en six couches : domaine et DNS, TLS, en-têtes HTTP, application, dépendances et serveur
Sécurité web en six couches : domaine et DNS, TLS, en-têtes HTTP, application, dépendances et serveur

Point clé

La sécurité web se construit par couches : verrouillez le domaine et le DNS (registrar lock, DNSSEC, CAA), imposez un TLS moderne avec HSTS, envoyez un ensemble strict d'en-têtes de sécurité HTTP, hachez les mots de passe avec Argon2id derrière la MFA et la limitation de débit, validez les entrées et appliquez le contrôle d'accès côté serveur, épinglez et auditez les dépendances, fermez chaque port que vous n'utilisez pas et journalisez suffisamment pour repérer une intrusion. Chaque pratique ci-dessous est accompagnée de la configuration exacte et d'un moyen gratuit de vérifier qu'elle est réellement en place, car un contrôle que vous n'avez pas testé est un contrôle que vous n'avez pas.

Advertisement

Ce que recouvre vraiment la sécurité web

Les bonnes pratiques de sécurité web désignent l'ensemble des contrôles qui empêchent un site ou une application web d'être piraté, défiguré, utilisé pour attaquer ses propres visiteurs ou discrètement vidé de ses données. Il ne s'agit ni d'un produit unique ni d'un simple réglage, mais d'une pile de décisions qui commence chez le registrar du domaine et traverse le DNS, le TLS, les en-têtes HTTP envoyés par votre serveur, le code qui gère les connexions et les entrées utilisateur, les paquets tiers sur lesquels vous bâtissez, le serveur lui-même et, pour finir, les journaux qui vous signalent qu'un problème est survenu.

Si l'on raisonne par couches, c'est parce que les attaquants le font. Le 2026 Data Breach Investigations Report de Verizon montre que 31 % des violations de données commencent désormais par l'exploitation d'une vulnérabilité logicielle, qui dépasse ainsi pour la première fois les identifiants volés comme principal point d'entrée, et que 48 % de toutes les violations impliquent un ransomware. Un seul correctif manquant, une clé d'API divulguée ou une page d'administration sans limitation de débit suffit. Aucun des contrôles de ce guide n'est exotique : les sites piratés sont généralement ceux qui ont négligé les bases sur une couche tout en peaufinant une autre.

Ce guide va de l'extérieur vers l'intérieur. Pour chaque pratique, il vous explique pourquoi elle compte, ce qu'il faut configurer exactement et comment le vérifier avec une commande ou un outil gratuit. En effet, l'erreur la plus fréquente que nous observons dans les vérifications d'en-têtes HTTP et les vérifications SSL n'est pas une mauvaise décision, mais un réglage que quelqu'un croyait activé sans jamais l'avoir confirmé.

Note

Si vous n'avez qu'une heure : activez le registrar lock et la MFA chez votre registrar, imposez HTTPS avec HSTS, ajoutez les en-têtes de sécurité du tableau de la couche 3, hachez les mots de passe avec Argon2id, mettez à jour toute dépendance touchée par une CVE connue et fermez tous les ports sauf 80 et 443. Cela couvre les points d'entrée de la grande majorité des intrusions web réelles.

La pile de sécurité web : six couches à protéger

Toute attaque contre un site web vise l'une de ces six couches. Le tableau ci-dessous sert de carte pour la suite du guide : ce que contient chaque couche, comment elle est généralement attaquée et quelle vérification gratuite confirme que votre défense est bien en place.

CoucheCe que font les attaquantsPratiques essentiellesVérifier avec
1. Domaine et DNSDétourner le domaine, modifier les serveurs de noms, s'emparer de sous-domaines orphelins, obtenir des certificats frauduleuxRegistrar lock, MFA, DNSSEC, CAA, audit des enregistrements obsolètesRecherche WHOIS, Recherche DNS, Recherche de Sous-domaines
2. Transport (TLS)Rétrograder vers HTTP, retirer le chiffrement, exploiter d'anciennes suites de chiffrement, profiter de certificats expirésTLS 1.2+, HSTS avec preload, renouvellement automatiséVérification du Certificat SSL
3. En-têtes HTTPInjecter des scripts (XSS), piéger le site dans un cadre (clickjacking), exploiter le MIME sniffing, faire fuiter le référentCSP, frame-ancestors, nosniff, Referrer-Policy, Permissions-PolicyVérification des En-têtes HTTP
4. ApplicationCredential stuffing, injection, contrôle d'accès défaillant, CSRF, uploads non sécurisésArgon2id + MFA + limitation de débit, requêtes paramétrées, autorisation côté serveur, cookies SameSiteRevue de code, OWASP ZAP, Test de Force de Mot de Passe
5. DépendancesPaquets empoisonnés, CVE connues dans les bibliothèques, pipelines CI compromisLockfiles, audits, versions épinglées, SBOM, jetons à privilèges minimauxnpm audit, Dependabot, Trivy
6. Serveur et exploitationPorts ouverts, identifiants par défaut, correctifs manquants, aucune sauvegarde, aucun journalPare-feu, SSH par clé uniquement, correctifs, sauvegardes 3-2-1, journalisation centraliséeVérificateur de Ports, Vérification de Liste Noire IP, Vérificateur de Santé du Domaine

Astuce

Procédez de haut en bas. Les couches 1 à 3 relèvent de la configuration : vous pouvez les boucler en un après-midi, et elles protègent toutes les pages d'un coup. Les couches 4 à 6 sont des habitudes permanentes qui doivent s'inscrire dans votre revue de code et votre processus de déploiement.

Advertisement

Couche 1 : verrouiller le domaine et le DNS

Tout le reste de ce guide suppose que vous contrôlez toujours votre domaine. Si un attaquant peut se connecter à votre compte chez le registrar ou modifier vos serveurs de noms, il peut rediriger votre trafic où il veut, obtenir un certificat valide pour votre nom et lire chaque e-mail qui vous est adressé, sans que votre code applicatif ne s'exécute jamais. La sécurité du domaine et du DNS est donc la première bonne pratique de sécurité web, et elle relève presque entièrement de la configuration.

Commencez par une recherche WHOIS sur votre propre domaine et vérifiez trois choses : les codes de statut incluent clientTransferProhibited, la date d'expiration est à plus d'un an et le registrar est bien un registrar chez qui vous avez réellement un compte. Il est étonnamment fréquent qu'un domaine d'entreprise se trouve dans le compte registrar d'un ancien prestataire. Notre guide de la recherche WHOIS explique chaque code de statut que vous rencontrerez.

Registrar lock, MFA et alertes d'expiration

Activez le registrar lock (aussi appelé verrou de transfert) afin que le domaine ne puisse pas être transféré vers un autre registrar sans que vous le déverrouilliez explicitement, et activez l'authentification multifacteur sur le compte registrar lui-même. Les comptes registrar sont une cible de phishing privilégiée précisément parce qu'un seul identifiant contrôle tout ce qui en dépend. Utilisez une clé matérielle ou une application d'authentification plutôt que le SMS dès que le registrar le permet.

Configurez le renouvellement automatique du domaine avec un moyen de paiement qui n'expirera pas, et ajoutez malgré tout une alerte dans votre agenda 60 jours avant la date d'expiration. Les domaines expirés sont récupérés par des drop-catchers en quelques heures, et l'acheteur hérite de vos e-mails, de votre trafic et de toutes les connexions OAuth qui font confiance à votre domaine.

  • Le registry lock (un verrou manuel, hors bande, au niveau du registre) vaut le surcoût pour un domaine dont dépend une entreprise : il empêche même un compte registrar compromis de modifier les serveurs de noms.

  • Séparez les rôles. La personne qui paie le domaine, le compte qui le détient et le fournisseur DNS doivent chacun être documentés et ne pas dépendre de la boîte mail d'un seul employé.

  • Activez la confidentialité WHOIS pour que vos coordonnées ne servent pas de carte aux campagnes de phishing, et gardez sur le compte une adresse de rôle surveillée comme domains@.

Signer la zone avec DNSSEC

DNSSEC signe votre zone DNS afin qu'un résolveur puisse détecter les réponses falsifiées. Sans lui, un attaquant capable d'empoisonner le cache d'un résolveur peut envoyer vos visiteurs vers un faux serveur alors que leur navigateur affiche toujours votre nom de domaine. La plupart des fournisseurs DNS managés (Cloudflare, Route 53, Google Cloud DNS et de nombreux registrars) l'activent d'un simple clic ; la seule étape manuelle consiste à publier l'enregistrement DS chez votre registrar. Vérifiez-le avec dig, ou avec le contrôle DNSSEC intégré au Vérificateur de Santé du Domaine :

bash
dig +dnssec +short yourdomain.com A
# A signed zone returns the record AND an RRSIG line:
# 203.0.113.10
# A 13 2 3600 20261015000000 20260924000000 34505 yourdomain.com. Kx3f...==

dig +short yourdomain.com DS
# A DS record at the parent zone proves the chain of trust is complete
# 34505 13 2 6A1B...C9

Restreindre l'émission de certificats avec CAA

Un enregistrement CAA (RFC 8659) indique aux autorités de certification lesquelles d'entre elles peuvent émettre des certificats pour votre domaine. Toute AC publique est tenue de le vérifier avant d'émettre, si bien qu'un enregistrement CAA ferme la porte à un attaquant qui aurait trompé la validation de domaine d'une autre AC. Trois enregistrements couvrent les cas courants : qui peut émettre, qui peut émettre des certificats wildcard et où signaler une demande refusée :

dns
yourdomain.com.  CAA 0 issue "letsencrypt.org"
yourdomain.com.  CAA 0 issuewild ";"
yourdomain.com.  CAA 0 iodef "mailto:security@yourdomain.com"

Avertissement

Avant d'ajouter CAA, listez toutes les AC qui émettent actuellement des certificats pour vous, y compris celle qui se cache derrière votre CDN ou votre panneau d'hébergement (Cloudflare alterne entre plusieurs AC ; de nombreux hébergeurs utilisent Sectigo ou Let's Encrypt). Un enregistrement CAA qui omet votre véritable AC fera échouer silencieusement le prochain renouvellement. Vérifiez d'abord l'émetteur actuel avec la Vérification du Certificat SSL.

Auditer les enregistrements obsolètes : subdomain takeover

Un subdomain takeover (prise de contrôle de sous-domaine) se produit lorsqu'un enregistrement DNS pointe encore vers un service que vous n'utilisez plus : un CNAME vers un site GitHub Pages supprimé, une application Azure, un bucket S3 ou le nom d'hôte d'un fournisseur SaaS. N'importe qui peut enregistrer la cible abandonnée, puis servir du contenu sur old-app.yourdomain.com en votre nom, certificat valide compris. C'est l'une des découvertes les plus fréquentes des programmes de bug bounty, car personne ne se souvient que l'enregistrement existe.

Passez votre domaine dans la Recherche de Sous-domaines, qui lit les journaux Certificate Transparency : vous voyez ainsi tous les noms d'hôte pour lesquels un certificat a déjà été émis. Résolvez ensuite chacun d'eux avec une recherche DNS et supprimez tout enregistrement dont la cible renvoie NXDOMAIN ou une page « no such app » d'un fournisseur. Recommencez chaque trimestre et intégrez la suppression de l'enregistrement DNS au démantèlement de chaque service.

Astuce

La Certificate Transparency est aussi votre système d'alerte précoce : Cert Spotter et la surveillance CT de Cloudflare peuvent vous envoyer un e-mail dès qu'une AC émet un certificat pour votre domaine. Un certificat inattendu est souvent le premier signe visible d'une compromission du DNS ou du compte registrar.

Couche 2 : HTTPS et TLS bien configurés

HTTPS n'est plus une bonne pratique : c'est le strict minimum, et les navigateurs marquent les pages en HTTP simple comme « Non sécurisé ». Ce qui distingue encore un site sécurisé d'un site simplement chiffré, ce sont les versions de TLS que vous acceptez, le fait qu'on puisse ou non vous joindre en HTTP, et un renouvellement suffisamment automatisé pour résister à la réduction de la durée de vie des certificats entamée en mars 2026.

Advertisement

TLS 1.2 au minimum, TLS 1.3 de préférence

TLS 1.0 et 1.1 ont été officiellement dépréciés par la RFC 8996 en 2021, et aucun navigateur actuel ne les négocie. Désactivez-les sur le serveur, privilégiez TLS 1.3 (qui supprime toutes les suites de chiffrement réputées faibles et termine la négociation en un seul aller-retour) et ne conservez TLS 1.2 qu'avec des suites AEAD comme ECDHE-ECDSA-AES128-GCM-SHA256 ou ECDHE-RSA-CHACHA20-POLY1305.

Deux lignes comptent quand vous testez depuis l'extérieur : le protocole négocié, et Verify return code: 0, qui signifie que toute la chaîne de certificats a été validée. Un certificat intermédiaire manquant est la cause la plus fréquente des signalements du type « ça marche dans Chrome, mais pas avec curl ni sur Android » ; notre guide sur la chaîne de certificats SSL explique comment corriger le problème, et la Vérification du Certificat SSL signale directement une chaîne incomplète. Voici le test exécuté sur dnsrobot.net :

bash
echo | openssl s_client -connect dnsrobot.net:443 -servername dnsrobot.net 2>/dev/null \
  | grep -E 'Protocol|Cipher|Verify return'

# Protocol  : TLSv1.3
# Cipher    : TLS_AES_256_GCM_SHA384
# Verify return code: 0 (ok)

# Confirm the old versions are refused:
openssl s_client -connect dnsrobot.net:443 -tls1_1 2>&1 | grep -iE 'alert|no protocols'

Note

C'est dans les listes de suites de chiffrement que les configurations copiées-collées vieillissent le plus vite. Au lieu de les écrire à la main, générez le bloc serveur actuellement recommandé pour nginx, Apache, Caddy ou HAProxy avec le Mozilla SSL Configuration Generator et choisissez le profil « Intermediate », sauf si vous devez prendre en charge des clients très anciens.

HSTS : ne plus jamais laisser un navigateur utiliser HTTP

Rediriger HTTP vers HTTPS ne suffit pas à lui seul. La toute première requête d'un visiteur vers http://yourdomain.com circule toujours en clair, et un attaquant présent sur le même réseau peut y répondre avant votre redirection. HTTP Strict Transport Security (RFC 6797) règle ce problème : dès qu'un navigateur a vu l'en-tête, il réécrit chaque future URL http:// de votre domaine en https:// avant d'envoyer quoi que ce soit.

Utilisez un max-age d'au moins un an (31536000 secondes), ajoutez includeSubDomains dès que tous vos sous-domaines servent du HTTPS, puis soumettez le domaine sur hstspreload.org pour qu'il soit codé en dur dans Chrome, Firefox, Safari et Edge. Le préchargement élimine complètement la faille de la première visite. Vérifiez l'en-tête avec la Vérification des En-têtes HTTP, qui note HSTS dans son score de sécurité de A à F.

http
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

Avertissement

HSTS est une porte à sens unique. Une fois includeSubDomains préchargé, tout sous-domaine incapable de servir un HTTPS valide, y compris les outils internes et un hôte dev. oublié, devient inaccessible dans les navigateurs. Déployez-le par étapes : max-age=300 pendant une semaine, puis un mois, puis un an, et n'ajoutez preload qu'ensuite.

Certificats de 47 jours : automatisez le renouvellement dès maintenant

Le vote SC-081 du CA/Browser Forum réduit par étapes la durée de vie maximale de tout certificat TLS public. La première réduction est entrée en vigueur le 15 mars 2026 : tout certificat acheté ou renouvelé aujourd'hui est donc déjà limité à 200 jours, et d'ici 2029 il faudra remplacer un certificat environ toutes les six semaines :

Date d'entrée en vigueurValidité maximale du certificatRéutilisation de la validation de domaine
Avant le 15 mars 2026398 jours398 jours
15 mars 2026200 jours200 jours
15 mars 2027100 jours100 jours
15 mars 202947 jours10 jours

Un renouvellement manuel ne tient pas face à ce calendrier. La bonne pratique consiste à automatiser entièrement l'émission via ACME : Let's Encrypt ou Google Trust Services avec certbot, acme.sh ou Caddy, ou encore les certificats automatiques intégrés à Cloudflare, Vercel, Netlify et à la plupart des panneaux d'hébergement. Testez la procédure de renouvellement avant d'en avoir besoin (certbot renew --dry-run pour certbot) ; l'échec à surveiller est un enregistrement CAA ou une règle de pare-feu ajoutés depuis le dernier renouvellement et qui bloquent désormais la validation. Quelle que soit votre solution, surveillez aussi la date d'expiration depuis l'extérieur : la Vérification du Certificat SSL affiche le nombre de jours restants, et un certificat expiré transforme chaque visite en avertissement plein écran du navigateur.

Couche 3 : en-têtes de sécurité HTTP

Les en-têtes de sécurité sont des instructions que votre serveur donne au navigateur sur ce qu'il peut faire ou non avec vos pages : quels scripts peuvent s'exécuter, si la page peut être intégrée dans un cadre, si le navigateur peut deviner les types de contenu et ce qu'il doit dire aux autres sites sur la provenance d'un visiteur. Ils ne coûtent rien, s'appliquent à toutes les pages à la fois et bloquent des catégories entières d'attaques. C'est aussi la couche que la plupart des sites configurent à moitié, et c'est pourquoi la Vérification des En-têtes HTTP leur attribue une note. Voici ce qu'envoie dnsrobot.net, limité aux en-têtes de sécurité :

bash
curl -sI https://dnsrobot.net/ | grep -iE 'strict-transport|content-security|x-frame|x-content-type|referrer-policy|permissions-policy'

strict-transport-security: max-age=31536000; includeSubDomains; preload
content-security-policy: default-src 'self'; script-src 'self' ... https://*.googletagmanager.com; frame-ancestors 'none'; base-uri 'self'; form-action 'self'
x-frame-options: DENY
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(self), microphone=(), geolocation=(), payment=(), usb=()

Les sept en-têtes que tout site devrait envoyer

Voici les valeurs à viser pour un site classique. Les cinq premiers sont ceux qui font évoluer votre note ; les deux derniers sont des ajouts peu coûteux une fois les autres en place.

En-têteValeur recommandéeCe qu'il empêche
Strict-Transport-Securitymax-age=31536000; includeSubDomains; preloadRétrogradation de protocole, vol de cookies via HTTP
Content-Security-Policyscript-src à base de nonce avec 'strict-dynamic' ; object-src 'none' ; base-uri 'none' ; frame-ancestors 'none'Cross-site scripting (XSS), injection de données, clickjacking
X-Content-Type-OptionsnosniffLe MIME sniffing qui transforme un fichier uploadé en script exécutable
Referrer-Policystrict-origin-when-cross-originFuite d'URL complètes (jetons, termes de recherche) vers des tiers
Permissions-Policycamera=(), microphone=(), geolocation=(), payment=()Scripts tiers qui utilisent en silence des API puissantes du navigateur
X-Frame-OptionsDENY (repli historique pour frame-ancestors)Clickjacking dans les navigateurs sans CSP Level 2
Cross-Origin-Opener-Policysame-originAttaques inter-fenêtres via window.opener

Content Security Policy sans casser le site

Une Content Security Policy est la défense la plus efficace contre le XSS, car elle empêche les scripts injectés de s'exécuter même lorsqu'une faille d'injection existe. Le revers : une politique stricte casse tout script inline ou toute balise tierce que vous auriez oubliés. L'approche moderne, recommandée par Google et documentée sur MDN, est une politique à base de nonce : le serveur génère un nonce aléatoire pour chaque réponse, le place sur chaque balise script qu'il affiche volontairement, et le navigateur refuse tout le reste.

C'est 'strict-dynamic' qui rend la politique utilisable en pratique : un script doté d'un nonce peut charger d'autres scripts (analytics, gestionnaires de balises, widgets) sans que chacun doive figurer sur une liste d'autorisation, tandis que les jetons https: et 'unsafe-inline' sont ignorés par les navigateurs modernes et ne servent que de repli pour les anciens. Déployez d'abord avec Content-Security-Policy-Report-Only, surveillez les rapports de violation pendant une semaine, puis passez en mode bloquant. Des frameworks comme Next.js, Rails et Django prennent en charge les nonces nativement ; les sites statiques peuvent utiliser à la place un script-src à base de hash.

http
Content-Security-Policy:
  script-src 'nonce-r4nd0m1z3dV4lu3' 'strict-dynamic' https: 'unsafe-inline';
  object-src 'none';
  base-uri 'none';
  frame-ancestors 'none';
  form-action 'self';
  report-to csp-endpoint

<!-- Only scripts carrying the nonce run; strict-dynamic lets them load their own dependencies -->
<script nonce="r4nd0m1z3dV4lu3" src="/app.js"></script>

Note

Une politique à liste d'autorisation comme script-src 'self' https://cdn.example.com vaut mieux que rien, mais n'importe quel endpoint JSONP ou ancienne bibliothèque hébergés sur un domaine autorisé peut servir à la contourner. Si vous ne pouvez pas encore utiliser de nonces, définissez au moins object-src 'none' et base-uri 'none', qui ferment immédiatement deux contournements courants.

Clickjacking : frame-ancestors et X-Frame-Options

Le clickjacking charge votre site de façon invisible dans la page d'un attaquant et pousse le visiteur à cliquer sur un bouton qu'il ne voit pas. frame-ancestors 'none' dans la CSP (ou 'self' si vous intégrez vos propres pages) l'empêche dans tous les navigateurs actuels, et X-Frame-Options: DENY couvre les plus anciens. Si vous proposez volontairement un widget intégrable, n'exemptez que ce chemin et uniquement pour les origines qui en ont besoin ; notre guide X-Frame-Options détaille les règles serveur exactes et les erreurs « refused to connect » que vous rencontrerez pendant vos tests.

nosniff, Referrer-Policy, Permissions-Policy et COOP

X-Content-Type-Options: nosniff empêche le navigateur de remettre en cause un Content-Type, ce qui est précisément ce qui transforme une « image » contenant du HTML, uploadée par un utilisateur, en page exécutable. Referrer-Policy: strict-origin-when-cross-origin (le comportement par défaut des navigateurs actuels, mais définissez-le explicitement) n'envoie que votre origine aux autres sites, si bien que les jetons de réinitialisation de mot de passe et les requêtes de recherche présents dans les URL restent privés. Permissions-Policy désactive les fonctionnalités du navigateur que vous n'utilisez pas, pour qu'un script tiers compromis ne puisse ni ouvrir la caméra ni lire la localisation. Cross-Origin-Opener-Policy: same-origin coupe le lien window.opener vers les pages que vous ouvrez, ce qui bloque toute une catégorie d'attaques inter-fenêtres.

Les en-têtes à supprimer comptent aussi : Server et X-Powered-By affichent les versions exactes de vos logiciels aux scanners de vulnérabilités, et X-XSS-Protection est obsolète et peut provoquer des bugs dans les anciens navigateurs ; réglez-le donc sur 0 ou retirez-le. Le Détecteur de CMS montre ce qu'un scanner apprend de votre stack à partir des seuls en-têtes.

Astuce

Définissez les en-têtes une seule fois en périphérie (CDN, reverse proxy ou middleware du framework) plutôt que page par page. Dans Next.js, c'est le fichier proxy ou middleware ; dans nginx, un bloc add_header dans le contexte server ; dans Apache, Header always set. Relancez ensuite la Vérification des En-têtes HTTP après chaque déploiement, car une nouvelle version du framework ou un réglage du CDN peut en supprimer un sans prévenir.

Couche 4 : une authentification qui résiste au credential stuffing

Les attaquants devinent rarement les mots de passe un par un. Ils rejouent des milliards de couples e-mail/mot de passe divulgués par d'autres sites (credential stuffing) et obtiennent le reste par phishing. Les bonnes pratiques d'authentification comportent donc trois volets : stocker les mots de passe de sorte qu'une fuite de base de données ne soit pas une fuite de mots de passe, rendre un mot de passe volé inutilisable à lui seul, et rendre la force brute trop lente pour être efficace. L'OWASP classe les Authentication Failures (défaillances d'authentification) en A07 dans l'OWASP Top 10:2025.

Advertisement

Hacher les mots de passe avec Argon2id ou bcrypt

Ne stockez jamais un mot de passe, ni même un hash rapide de celui-ci. MD5, SHA-1 et même SHA-256 sont conçus pour être rapides : une table divulguée de ces hashs peut être testée à raison de milliards de tentatives par seconde sur un seul GPU. Utilisez une fonction de hachage de mots de passe lente et gourmande en mémoire avec un sel unique par mot de passe. L'OWASP Password Storage Cheat Sheet recommande, dans l'ordre :

  • Argon2id avec au moins 19 Mio de mémoire, 2 itérations et un degré de parallélisme de 1 (ou 46 Mio avec 1 itération).

  • scrypt avec N = 2^17, r = 8, p = 1 lorsque Argon2 n'est pas disponible.

  • bcrypt avec un facteur de coût de 10 ou plus (attention à sa limite d'entrée de 72 octets ; le pré-hachage des mots de passe plus longs demande des précautions).

  • PBKDF2-HMAC-SHA256 avec 600 000 itérations, uniquement lorsque la conformité FIPS l'impose.

javascript
// Node.js with the argon2 package
import argon2 from "argon2";

const hash = await argon2.hash(password, {
  type: argon2.argon2id,
  memoryCost: 19456, // KiB = 19 MiB
  timeCost: 2,
  parallelism: 1,
});

// Later, on login:
const ok = await argon2.verify(hash, submittedPassword);

Note

Réglez le coût pour qu'un hash prenne environ 100 à 250 ms sur votre serveur de connexion. C'est imperceptible pour un utilisateur réel, mais cela limite un attaquant à quelques milliers de tentatives par seconde et par cœur au lieu de milliards. Recalculez le hash à la connexion réussie chaque fois que vous augmentez les paramètres, pour que les anciens hashs se mettent à niveau d'eux-mêmes.

Des règles de mot de passe vraiment utiles (NIST SP 800-63B)

Les règles de composition que la plupart des sites imposent encore (une majuscule, un symbole, un changement tous les 90 jours) produisent des mots de passe prévisibles comme Summer2026! et poussent les gens à les réutiliser. Les recommandations actuelles du NIST SP 800-63B les remplacent par des règles qui mesurent ce qui compte vraiment :

  • Au minimum 8 caractères lorsque la MFA est également exigée, et au moins 15 caractères pour un mot de passe utilisé seul ; autorisez-en au moins 64.

  • Aucune règle de composition et aucune rotation périodique forcée ; n'exigez un changement qu'en cas de preuve de compromission.

  • Vérifiez chaque nouveau mot de passe dans une liste de fuites (l'API par plage de Have I Been Pwned permet de le faire sans envoyer le mot de passe) et refusez ceux qui ont déjà fuité.

  • Autorisez le copier-coller et les gestionnaires de mots de passe, acceptez les espaces et l'Unicode, et affichez un indicateur de robustesse fondé sur l'entropie plutôt que sur des règles.

Notre Test de Force de Mot de Passe montre en quoi ces critères diffèrent des anciennes règles : il estime le temps de cassage à partir de l'entropie et de la détection de motifs, et vérifie le mot de passe dans des données de fuites, ce qui est bien plus utile qu'un message rouge « symbole requis ».

MFA et passkeys

L'authentification multifacteur transforme un mot de passe volé en impasse. Proposez-la à tout le monde et exigez-la pour les rôles d'administration, de finance et de support. Classez les options selon leur résistance au phishing : les passkeys et clés de sécurité FIDO2 ne peuvent pas être hameçonnées, car l'identifiant est lié à votre véritable origine ; les applications d'authentification (TOTP) sont une bonne option ; les codes SMS valent mieux que rien, mais peuvent être interceptés par SIM swapping. Les passkeys sont prises en charge par tous les navigateurs et systèmes d'exploitation actuels et suppriment complètement le mot de passe, ce qui élimine du même coup toute la catégorie du credential stuffing.

Protégez la procédure de récupération avec autant de soin que la connexion : codes de récupération stockés sous forme hachée, réinitialisations par e-mail avec des jetons à usage unique qui expirent en 15 minutes, et aucune question de sécurité.

Limitation de débit, verrouillage et défense anti-bots

Appliquez une limitation de débit aux endpoints de connexion, d'inscription, de réinitialisation de mot de passe et de MFA, par IP et par compte, et renvoyez 429 Too Many Requests avec un en-tête Retry-After une fois la limite atteinte (notre guide sur l'erreur HTTP 429 explique comment les clients doivent réagir). Combinez-la avec un délai croissant ou un verrouillage temporaire après des échecs répétés sur un même compte, et avec un CAPTCHA ou un défi proof-of-work pour les endpoints visés par des attaques distribuées. Journalisez chaque échec de connexion avec l'IP source, afin que le schéma d'une campagne de credential stuffing soit visible en quelques minutes plutôt qu'en quelques mois.

nginx
# nginx: 5 login attempts per minute per client IP
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;

location = /api/login {
    limit_req zone=login burst=4 nodelay;
    limit_req_status 429;
    proxy_pass http://app;
}

Avertissement

Gardez des messages d'erreur identiques pour « utilisateur inconnu » et « mot de passe incorrect », et un temps de réponse identique dans les deux cas (hachez un mot de passe factice lorsque l'utilisateur n'existe pas). Sinon, le formulaire de connexion sert aussi d'API d'énumération des utilisateurs.

Sessions, cookies et CSRF

Après la connexion, le cookie de session est l'utilisateur ; il mérite donc la même protection que le mot de passe. Trois attributs de cookie et un préfixe de nom font l'essentiel du travail :

  • Secure signifie que le cookie n'est jamais envoyé en HTTP simple ; il ne peut donc pas être intercepté sur un Wi-Fi public.

  • HttpOnly le rend invisible pour JavaScript, si bien qu'une faille XSS ne peut pas le lire.

  • SameSite=Lax (ou Strict pour les panneaux d'administration) l'exclut des requêtes POST intersites, ce qui neutralise la plupart des attaques CSRF.

  • Le préfixe __Host- amène le navigateur à refuser le cookie s'il n'est pas Secure, s'il n'a pas Path=/ ou s'il possède un attribut Domain, si bien qu'un sous-domaine ne peut pas l'écraser.

http
Set-Cookie: __Host-session=9f1c7e2a...; Path=/; Secure; HttpOnly; SameSite=Lax; Max-Age=28800

Astuce

Les actions qui modifient un état ne doivent jamais être accessibles en GET. Un lien comme /account/delete?id=42 peut être déclenché par une balise <img> sur n'importe quelle page visitée par l'utilisateur, aussi bons que soient les attributs de vos cookies.

CSRF : une seconde ligne de défense derrière SameSite

Le cross-site request forgery (CSRF) pousse un navigateur connecté à envoyer à votre site, depuis une autre page, une requête qui modifie un état. Les cookies SameSite bloquent le cas courant, mais conservez une seconde défense sur chaque requête non-GET : un jeton anti-CSRF par session dans un champ caché ou un en-tête personnalisé, ou une vérification que l'en-tête Origin (ou Sec-Fetch-Site) correspond bien à votre propre origine. La plupart des frameworks (Django, Rails, Laravel, les server actions de Next.js) le font par défaut ; l'erreur consiste à désactiver cette protection pour un endpoint d'API, puis à appeler cet endpoint depuis un navigateur.

ID de session, rotation et JWT

Générez des identifiants de session avec au moins 128 bits d'aléa, changez l'identifiant à la connexion et à chaque changement de privilèges pour déjouer la fixation de session, faites expirer les sessions après une période d'inactivité et offrez aux utilisateurs un bouton « se déconnecter partout » qui les invalide côté serveur. Pour les JWT, gardez-les de courte durée (quelques minutes, avec un refresh token révocable), ne les stockez jamais dans localStorage où n'importe quel script peut les lire, et traitez la fuite d'une clé de signature comme une compromission totale, car chaque jeton qu'elle a signé devient falsifiable.

Injection et XSS : valider les entrées, encoder les sorties

L'injection (A05:2025) et le cross-site scripting sont la même erreur commise à des endroits différents : des données fournies par un utilisateur sont transmises à un interpréteur (SQL, le shell, une requête LDAP, une page HTML) comme s'il s'agissait de code. La correction est partout la même : séparer les données du code et ne jamais construire une commande par concaténation de chaînes.

Advertisement

Des requêtes paramétrées, pas de concaténation

Pour SQL, utilisez des requêtes préparées ou un ORM qui les génère : la base de données traite alors l'entrée comme une valeur qui ne peut jamais modifier la structure de la requête. La même règle s'applique aux commandes shell (passez un tableau d'arguments, jamais une chaîne), aux filtres NoSQL (rejetez les objets opérateurs comme {"$gt": ""} dans les entrées utilisateur) et aux chemins de fichiers (résolvez le chemin et vérifiez qu'il reste sous le répertoire prévu).

javascript
// Vulnerable: the input becomes part of the query text
const rows = await db.query(`SELECT * FROM users WHERE email = '${email}'`);

// Safe: the driver sends the value separately from the query
const rows = await db.query("SELECT * FROM users WHERE email = $1", [email]);

// Python / psycopg: same idea
cur.execute("SELECT * FROM users WHERE email = %s", (email,))

L'encodage des sorties arrête le XSS

Le cross-site scripting se produit lorsqu'un texte contrôlé par l'utilisateur est écrit dans une page sans être encodé pour le contexte où il atterrit. Les moteurs de templates modernes (React et JSX, Vue, Jinja2, Blade, ERB) encodent par défaut ; aujourd'hui, le XSS vient généralement des échappatoires : dangerouslySetInnerHTML, v-html, |safe, innerHTML, et la construction d'URL ou de gestionnaires d'événements inline à partir de données utilisateur. Encodez pour le contexte exact et nettoyez le HTML riche avec une bibliothèque dédiée comme DOMPurify plutôt qu'avec une regex.

Où arrivent les donnéesEncoder enExemple
Corps HTMLEntités HTML< devient &lt;, " devient &quot;
Attribut HTMLEntités pour attributs entre guillemetsMettez toujours l'attribut entre guillemets ; encodez " et '
JavaScriptN'injectez rien dans le texte du script ; transmettez les données via des attributs data- ou un bloc JSON <script type="application/json"></script> dans une chaîne devient \u003c/script\u003e
Paramètre d'URLEncodage-pourcent (percent-encoding)encodeURIComponent(value)
Valeur CSSÀ éviter totalement ; choisissez les noms de classes dans une liste d'autorisationN'interpolez jamais d'entrée utilisateur dans style

SSRF, uploads de fichiers et désérialisation

Server-side request forgery (SSRF) : si votre serveur récupère une URL fournie par un utilisateur (webhooks, proxys d'images, aperçus de liens), un attaquant peut la faire pointer vers des services internes ou vers l'endpoint de métadonnées cloud 169.254.169.254 et y lire des identifiants. Résolvez d'abord le nom d'hôte, rejetez les plages privées et link-local, désactivez les redirections et placez les composants chargés de ces requêtes sur un segment réseau qui ne peut rien atteindre en interne.

Uploads de fichiers : validez le type en inspectant le contenu, et non l'extension ou le Content-Type envoyé par le client ; imposez une limite de taille ; stockez les fichiers hors de la racine web ou dans un stockage objet, sous un nom aléatoire que vous générez ; et servez-les depuis une origine distincte avec nosniff et Content-Disposition: attachment lorsque c'est possible. Ne laissez jamais un upload atterrir à un endroit où le serveur web l'exécutera.

Désérialisation et mass assignment : ne désérialisez jamais de données non fiables avec un format capable d'instancier des classes arbitraires (sérialisation native Java, pickle en Python, unserialize en PHP, YAML avec des tags personnalisés) ; utilisez du JSON avec un schéma. Liez les corps de requête à une liste explicite de champs autorisés, afin qu'un utilisateur ne puisse pas envoyer "role": "admin" par POST dans un modèle qui possède justement cette colonne.

Avertissement

La validation sert à contrôler la forme (est-ce un e-mail, un entier positif, l'une de ces cinq valeurs ?), pas à assurer la sécurité. Les listes de blocage qui suppriment <script> ou les guillemets peuvent toujours être contournées. N'acceptez que ce que vous attendez, puis encodez en sortie et paramétrez au stockage.

Broken Access Control : le risque numéro un

Le Broken Access Control (contrôle d'accès défaillant) occupe la première place de l'OWASP Top 10 depuis 2021 et la conserve en A01:2025. Ce n'est pas un bug isolé mais une habitude : vérifier qui est quelqu'un (authentification) et oublier de vérifier ce qu'il a le droit de toucher (autorisation) à chaque requête. La forme classique est l'insecure direct object reference (référence directe non sécurisée à un objet) : GET /api/invoices/1042 fonctionne pour le propriétaire de la facture, mais aussi pour quiconque modifie le numéro.

  • Refusez par défaut. Chaque route exige une règle explicite accordant l'accès ; une règle manquante signifie 403, pas 200.

  • Contrôlez côté serveur, objet par objet. Masquer un bouton dans l'interface n'est pas du contrôle d'accès. Chaque lecture et chaque écriture doit confirmer que l'utilisateur courant possède l'enregistrement concerné ou y est autorisé, y compris dans les endpoints groupés, les exports et les tâches en arrière-plan.

  • Utilisez des identifiants impossibles à deviner quand c'est utile (UUID), mais ne comptez jamais dessus : l'obscurité n'est pas une autorisation.

  • Verrouillez CORS. Access-Control-Allow-Origin: * avec des identifiants, ou le renvoi de n'importe quel Origin envoyé par la requête, livre votre API à tout site web visité par l'utilisateur.

  • Désactivez le listing des répertoires, bloquez .git, .env, les fichiers de sauvegarde et de configuration au niveau du serveur web, et gardez les panneaux d'administration hors de l'internet public ou derrière la MFA et des listes d'IP autorisées.

  • Limitez le débit et journalisez les échecs d'autorisation. Une rafale de 403 depuis une même session, c'est une attaque par énumération en cours.

javascript
// Express: ownership check on every object access
app.get("/api/invoices/:id", requireAuth, async (req, res) => {
  const invoice = await Invoice.findById(req.params.id);
  if (!invoice || invoice.ownerId !== req.user.id) {
    return res.status(404).end(); // 404, not 403: don't confirm the record exists
  }
  res.json(invoice);
});

Note

Testez le contrôle d'accès comme le ferait un attaquant : connectez-vous avec un utilisateur à faibles privilèges, capturez chaque requête et rejouez-les une à une avec les identifiants d'un autre utilisateur, puis sans l'en-tête Authorization. Les scanners automatiques trouvent les injections ; ils ne trouvent presque jamais les failles d'autorisation, et c'est pourquoi celles-ci survivent pendant des années.

Couche 5 : dépendances et chaîne d'approvisionnement logicielle

Une application web typique embarque peut-être 5 % de code que vous avez écrit et 95 % de code que vous avez téléchargé. C'est pourquoi les Software Supply Chain Failures (défaillances de la chaîne d'approvisionnement logicielle) font leur entrée en A03 dans l'OWASP Top 10 2025, et pourquoi l'exploitation de vulnérabilités a dépassé les identifiants volés dans le DBIR 2026. En septembre 2025, un seul mainteneur victime de phishing a introduit un malware de vol de cryptomonnaies dans chalk, debug et 16 autres paquets npm totalisant plus de deux milliards de téléchargements par semaine ; tout projet ayant installé une version non épinglée pendant cette fenêtre l'a récupéré automatiquement.

  • Commitez un lockfile (package-lock.json, yarn.lock, pnpm-lock.yaml, poetry.lock, go.sum) et installez avec npm ci en CI, pour que les builds soient reproductibles et qu'une nouvelle version publiée en amont ne puisse pas s'infiltrer sans relecture.

  • Analysez en continu : npm audit, pip-audit, bundler-audit, GitHub Dependabot ou Renovate pour les mises à jour, et un scanner de conteneurs comme Trivy ou Grype pour la couche système.

  • Retardez de quelques jours les mises à jour non liées à la sécurité (minimumReleaseAge de Renovate), pour qu'une version empoisonnée soit généralement retirée avant que vous ne l'adoptiez, mais appliquez immédiatement les correctifs de sécurité.

  • Épinglez les actions et scripts tiers sur un SHA de commit en CI, et utilisez Subresource Integrity (integrity="sha384-...") pour tout script chargé depuis un CDN public.

  • Accordez à la CI le moindre privilège : jetons en lecture seule lorsque c'est possible, identifiants OIDC de courte durée plutôt que des secrets à longue durée de vie, et droits de publication réservés à un job de release.

  • Générez un SBOM (CycloneDX ou SPDX) au moment du build, pour pouvoir répondre en quelques minutes à la question « sommes-nous concernés ? » quand tombera la prochaine CVE du calibre de Log4Shell.

bash
# Reproducible install + audit in CI
npm ci --ignore-scripts
npm audit --audit-level=high

# Pin a GitHub Action to a commit, not a floating tag
# uses: actions/checkout@v4                 <- can change underneath you
# uses: actions/checkout@<full-commit-sha>  # v4.2.2

# Subresource Integrity for a CDN script (hash from: openssl dgst -sha384 -binary lib.min.js | openssl base64 -A)
<script src="https://cdn.example.com/lib.min.js"
        integrity="sha384-<base64-hash>"
        crossorigin="anonymous"></script>

Astuce

npm ci --ignore-scripts bloque les scripts d'installation dont se servent la plupart des malwares npm pour s'exécuter ; réactivez ensuite les scripts uniquement pour la poignée de paquets qui ont réellement besoin d'une étape de build.

Si vous utilisez WordPress ou un autre CMS, les mêmes règles s'appliquent aux plugins et aux thèmes, par lesquels commencent la plupart des compromissions de CMS. Maintenez le cœur et chaque plugin à jour, supprimez ceux que vous n'utilisez pas et vérifiez ce qu'un scanner peut apprendre de vos versions avec le Détecteur de CMS.

Couche 6 : durcissement du serveur (ports, correctifs, secrets, sauvegardes)

La couche applicative ne sert à rien si le serveur sous-jacent accepte les connexions SSH par mot de passe, expose une base de données sur un port public ou n'a pas été mis à jour depuis son installation. Les bonnes pratiques côté serveur sont ennuyeuses, et c'est précisément par là que les ransomwares entrent.

Fermer chaque port que vous n'utilisez pas

Un serveur web public a besoin des ports 80 et 443 ouverts, et de SSH depuis votre propre plage d'IP. Les bases de données (3306, 5432, 27017), Redis (6379), Elasticsearch (9200), les panneaux d'administration et les endpoints de métriques doivent écouter uniquement sur localhost ou sur un réseau privé. Vérifiez depuis l'extérieur avec le Vérificateur de Ports après chaque modification, car c'est la vue dont dispose un attaquant, et les groupes de sécurité cloud sont faciles à mal interpréter.

bash
# Ubuntu: default-deny firewall, allow only web + SSH from your office range
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow from 203.0.113.0/24 to any port 22 proto tcp
sudo ufw enable

# SSH: keys only, no root password login
sudo sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
sudo sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin prohibit-password/' /etc/ssh/sshd_config
sudo systemctl reload ssh

Corriger selon un calendrier, garder les secrets hors du code

Activez les mises à jour de sécurité automatiques du système d'exploitation, abonnez-vous aux listes de sécurité de votre runtime et de votre framework, et traitez une CVE critique sur tout composant exposé à internet comme une tâche à régler dans la journée. Exécutez les services sous des utilisateurs non privilégiés, dans des conteneurs ou avec le sandboxing de systemd, pour qu'un processus compromis ne puisse pas lire toute la machine.

Les secrets (mots de passe de base de données, clés d'API, clés de signature) n'ont leur place ni dans le dépôt, ni dans une couche d'image Docker, ni dans le JavaScript côté client. Chargez-les depuis des variables d'environnement injectées au déploiement ou depuis un gestionnaire de secrets, renouvelez-les lorsqu'une personne qui y avait accès s'en va, et analysez l'historique du dépôt avec un outil comme gitleaks, car une clé commitée une seule fois est compromise pour toujours, même après la suppression du commit.

Avertissement

Tout ce qui est préfixé par NEXT_PUBLIC_, VITE_ ou REACT_APP_ est intégré au bundle envoyé au navigateur, et donc public par définition. Placez plutôt les clés d'API tierces derrière une route de votre propre serveur. Notre guide pour tester un endpoint d'API public montre comment vérifier ce que votre frontend expose réellement.

Des sauvegardes qui résistent aux ransomwares, et un CDN en frontal

Appliquez la règle 3-2-1 : trois copies, sur deux supports différents, dont une hors site, et rendez au moins une copie immuable ou hors ligne, afin qu'un ransomware qui atteint le serveur ne puisse pas chiffrer aussi les sauvegardes. Chiffrez les sauvegardes, incluez la base de données et le répertoire des uploads et surtout, testez une restauration à intervalles réguliers. Une sauvegarde à partir de laquelle personne n'a jamais restauré est un espoir, pas un plan. C'est le temps de reprise qui détermine si un incident sera une simple panne ou un événement fatal pour l'entreprise.

Placez un CDN ou un WAF (Cloudflare, Fastly, AWS CloudFront avec WAF, ou l'équivalent de votre hébergeur) devant l'origine. Il absorbe les DDoS volumétriques, applique des règles managées contre les charges d'injection courantes et les bots malveillants, masque l'IP de votre origine et vous offre un endroit où appliquer limitation de débit et règles géographiques sans toucher à l'application. Restreignez ensuite le pare-feu de l'origine pour que seules les plages d'IP du CDN puissent atteindre directement le port 443 ; sinon, les attaquants le contournent tout simplement. Le Vérificateur d'hébergement indique si l'origine réelle d'un site est exposée derrière son CDN.

Authentification des e-mails : SPF, DKIM et DMARC

La sécurité web englobe aussi les e-mails qui transportent vos réinitialisations de mot de passe, vos factures et vos réponses au support. Sans SPF, DKIM et DMARC, n'importe qui peut envoyer des e-mails en tant que billing@yourdomain.com, et depuis février 2024 Google et Yahoo exigent les trois de la part des expéditeurs en masse. L'ensemble complet tient en trois enregistrements DNS TXT :

dns
yourdomain.com.                    TXT  "v=spf1 include:_spf.google.com -all"
google._domainkey.yourdomain.com.  TXT  "v=DKIM1; k=rsa; p=MIIBIjANBgkq..."
_dmarc.yourdomain.com.             TXT  "v=DMARC1; p=reject; rua=mailto:dmarc@yourdomain.com; adkim=s; aspf=s"

Note

DMARC p=reject est aussi un outil de protection de la marque : c'est la seule chose qui empêche une campagne de phishing d'afficher votre domaine exact dans le champ « De ». Les rapports agrégés (rua=) vous montrent qui essaie.

Démarrez DMARC en p=none pour collecter les rapports, puis passez à p=quarantine et enfin à p=reject une fois que chaque expéditeur légitime (plateforme marketing, helpdesk, CRM) respecte l'alignement. Ajoutez des enregistrements MTA-STS et TLS-RPT pour imposer une livraison chiffrée vers vos serveurs de messagerie, et publiez un MX nul (MX 0 .) sur les domaines qui n'envoient jamais d'e-mails, pour qu'ils ne puissent pas du tout être usurpés. Vérifiez chaque enregistrement avec le Vérificateur d'Enregistrement SPF, le Vérificateur DKIM et le Vérificateur DMARC, et contrôlez vos IP d'envoi dans les listes de blocage avec la Vérification de Liste Noire IP si la délivrabilité chute.

Journaliser, surveiller et anticiper l'intrusion

Deux des dix catégories de l'OWASP 2025 portent sur ce qui se passe après une erreur : Security Logging and Alerting Failures (A09) et la nouvelle catégorie Mishandling of Exceptional Conditions (A10). Une intrusion typique passe encore inaperçue pendant des mois, parce que les preuves n'ont jamais été enregistrées, ou qu'elles l'ont été sans que personne ne les consulte.

  • Journalisez les événements de sécurité avec leur contexte : chaque connexion réussie ou échouée, les modifications de MFA, les réinitialisations de mot de passe, les changements de permissions, les refus du contrôle d'accès, les échecs de validation des entrées et les actions d'administration, chacun avec l'horodatage, l'ID utilisateur, l'IP source et le user agent.

  • Ne journalisez jamais de secrets : mots de passe, jetons de session, numéros de carte complets, clés d'API. Masquez-les au niveau de la couche de journalisation, pas à chaque point d'appel.

  • Envoyez les journaux hors du serveur vers un stockage centralisé (CloudWatch, Loki, Elastic, un SIEM) avec une rétention d'au moins 90 jours, pour qu'un attaquant ayant obtenu les droits root ne puisse pas effacer ses traces.

  • Déclenchez des alertes sur des schémas, pas sur des événements isolés : 50 échecs de connexion en une minute, un pic de 403 depuis une même session, un nouvel administrateur créé en dehors des heures ouvrées, un certificat émis pour votre domaine que vous n'avez pas demandé.

  • Échouez en mode fermé (fail closed) : lorsqu'un contrôle en aval (service d'authentification, limiteur de débit, WAF) renvoie une erreur, refusez la requête. La catégorie A10 existe parce que tant de systèmes accordent l'accès lorsque le contrôle qui aurait dû bloquer la requête lève une exception.

  • Surveillez depuis l'extérieur : disponibilité, expiration des certificats, modifications DNS, inscriptions sur des listes de blocage et régressions d'en-têtes. Le Vérificateur de Santé du Domaine regroupe les contrôles DNS, SSL, d'authentification des e-mails et d'en-têtes en un seul score que vous pouvez relancer après chaque déploiement.

Rédiger le plan de réponse aux incidents avant d'en avoir besoin

Décidez à l'avance qui est d'astreinte, comment renouveler chaque identifiant, comment passer le site en lecture seule, où se trouvent les sauvegardes saines, et quels régulateurs ou clients doivent être notifiés et dans quel délai (72 heures selon le RGPD). Organisez un exercice sur table une fois par an. Les équipes qui ont répété leur plan se rétablissent en quelques jours ; les autres improvisent pendant des semaines.

Astuce

Ajoutez un fichier security.txt à l'emplacement /.well-known/security.txt (RFC 9116) avec une adresse de contact et une clé PGP. Les chercheurs qui trouvent un bug sur votre site l'utiliseront ; sans lui, ils risquent de le rendre public.

Tester : scanners, tests d'intrusion et contrôles continus

Chacun des contrôles ci-dessus peut être vérifié, et cette vérification doit être automatisée autant que possible pour ne pas se dégrader avec le temps. Voici une progression raisonnable, du gratuit et instantané au périodique et payant :

ContrôleOutilFréquence
Configuration TLS, chaîne, expirationVérification du Certificat SSL, SSL Labs, testssl.shAprès chaque changement de certificat ou de serveur ; expiration tous les jours
En-têtes de sécurité et CSPVérification des En-têtes HTTP, MDN HTTP ObservatoryAprès chaque déploiement (intégrez-le à la CI)
Ports ouvertsVérificateur de Ports, nmapAprès chaque modification du pare-feu ou du cloud
DNS, DNSSEC, authentification des e-mailsVérificateur de Santé du Domaine, Vérificateur DMARCChaque mois, et après toute modification DNS
Sous-domaines obsolètesRecherche de Sous-domainesChaque trimestre et à chaque démantèlement
Dépendances connues comme vulnérablesnpm audit, Dependabot, TrivyÀ chaque build
Failles au niveau du code (SAST)Semgrep, CodeQLÀ chaque pull request
Vulnérabilités web à l'exécution (DAST)OWASP ZAP, NucleiChaque semaine sur l'environnement de staging
Autorisation et logique métierTest d'intrusion manuel ou programme de bug bountyChaque année, et après chaque fonctionnalité majeure

Les scanners sont efficaces sur les injections, les en-têtes et les composants obsolètes, mais mauvais sur l'autorisation et la logique métier : prévoyez donc au moins un test humain par an pour tout ce qui manipule de l'argent ou des données personnelles. Corrigez selon l'exposition : tout ce qu'un utilisateur non authentifié peut exploiter depuis internet passe en premier.

La checklist de sécurité web

Copiez-la dans le README de votre projet ou dans votre outil de suivi de tickets. Chaque ligne reprend l'une des pratiques ci-dessus, formulée pour pouvoir être cochée ou non ; la dernière colonne en apporte la preuve.

CouchePratiqueValidé quand
DomaineRegistrar lock et MFA sur le compte registrar ; renouvellement automatique activéLe WHOIS affiche clientTransferProhibited ; expiration à plus de 12 mois
DNSZone signée avec DNSSEC ; enregistrement CAA ne listant que vos ACdig +dnssec renvoie RRSIG ; enregistrement DS présent dans la zone parente
DNSAucun enregistrement CNAME ou A orphelinChaque nom d'hôte trouvé par la Recherche de Sous-domaines pointe vers une ressource que vous contrôlez
TLSTLS 1.2+ uniquement, TLS 1.3 de préférence, chaîne complète servieVérification du Certificat SSL : chaîne complète, TLS 1.0/1.1 refusés
TLSHSTS avec un max-age d'un an, includeSubDomains, préchargéInscrit sur hstspreload.org
TLSRenouvellement automatisé via ACME ; expiration surveilléecertbot renew --dry-run réussit ; alerte réglée à 14 jours
En-têtesCSP (à base de nonce), frame-ancestors, nosniff, Referrer-Policy, Permissions-PolicyNote A à la Vérification des En-têtes HTTP
AuthentificationHachage Argon2id ou bcrypt ; règles de mot de passe NIST ; vérification dans une liste de fuitesUn hash prend de 100 à 250 ms ; aucune règle de composition
AuthentificationMFA proposée à tous, obligatoire pour les administrateurs ; passkeys prises en chargeConnexion admin impossible sans second facteur
AuthentificationEndpoints de connexion, de réinitialisation et de MFA limités par IP et par compteLa sixième tentative en une minute renvoie 429
SessionsCookie __Host- avec Secure, HttpOnly, SameSite ; ID renouvelé à la connexionAttributs du cookie visibles dans les DevTools ; ancienne session invalide après connexion
EntréesRequêtes paramétrées partout ; sorties encodées selon le contexte ; uploads validés par leur contenuAucune requête construite par concaténation dans une recherche de code ; les payloads XSS s'affichent comme du texte
Contrôle d'accèsRoutage avec refus par défaut ; contrôle de propriété par objet ; CORS strictRejouer les ID d'un autre utilisateur renvoie 404 ou 403
DépendancesLockfile commité ; npm ci ; audit en CI ; actions épinglées par SHA ; SRI sur les scripts CDNLe build échoue sur une CVE de gravité élevée
ServeurSeuls 80 et 443 publics ; SSH par clé uniquement ; mises à jour de sécurité automatiques ; secrets en variables d'environnement ou dans un coffre-fortLe Vérificateur de Ports montre 22, 3306 et 6379 fermés depuis internet
Sauvegardes3-2-1 avec une copie immuable ; restauration testéeDernier test de restauration réussi datant de moins de 90 jours
E-mailSPF -all, DKIM, DMARC p=reject, MTA-STSLe Vérificateur DMARC valide ; rapports agrégés reçus
SurveillanceÉvénements d'authentification et d'autorisation journalisés de façon centralisée ; alertes sur des schémas ; surveillance externe de la disponibilité, des certificats et du DNSAlerte de test déclenchée et reçue
RéponsePlan d'incident écrit ; security.txt publié ; exercice sur table réaliséPlan revu au cours des 12 derniers mois

Correspondance avec l'OWASP Top 10:2025

L'OWASP Top 10 est la liste de risques des applications web la plus citée, et son édition 2025 a remanié l'ordre et introduit deux nouvelles catégories. Si un client, un auditeur ou un référentiel de conformité vous demande comment vous y répondez, voici la correspondance avec les pratiques de ce guide :

OWASP Top 10:2025Pratiques de ce guide
A01 Broken Access ControlRefus par défaut, contrôles par objet, CORS strict, verrouillage de l'administration
A02 Security MisconfigurationEn-têtes de sécurité, HSTS, ports fermés, en-têtes de version supprimés, listing des répertoires désactivé
A03 Software Supply Chain Failures (nouveau)Lockfiles, audits, actions épinglées, SRI, SBOM, CI à privilèges minimaux
A04 Cryptographic FailuresTLS 1.2+ et 1.3, HSTS, Argon2id, gestion des secrets, sauvegardes chiffrées
A05 InjectionRequêtes paramétrées, encodage des sorties, CSP, validation des uploads
A06 Insecure DesignModélisation des menaces par couche, comportement fail-closed par défaut, limitation de débit dès la conception
A07 Authentication FailuresRègles de mot de passe NIST, vérification des fuites, MFA et passkeys, rotation des sessions
A08 Software or Data Integrity FailuresSRI, dépendances signées et épinglées, désérialisation sûre
A09 Security Logging and Alerting FailuresJournalisation centralisée, alertes sur des schémas, surveillance externe
A10 Mishandling of Exceptional Conditions (nouveau)Fail closed, réponses d'erreur uniformes, aucune stack trace montrée aux utilisateurs

Note

L'ASVS de l'OWASP (Application Security Verification Standard) transforme ces mêmes éléments en checklist numérotée pour les audits. Le niveau 1 est un objectif réaliste pour tout site public ; le niveau 2 convient à tout ce qui traite des données personnelles ou financières.

Vérifiez les en-têtes de sécurité de votre site en quelques secondes

Le vérificateur d'en-têtes HTTP gratuit de DNS Robot analyse n'importe quelle URL et note ses en-têtes de sécurité de A à F : HSTS, Content-Security-Policy, X-Frame-Options, X-Content-Type-Options, Referrer-Policy et Permissions-Policy, avec la valeur exacte trouvée et ce qui manque. Sans inscription.

Essayer le vérificateur d'en-têtes HTTP

Advertisement

FAQ sur la sécurité web

Imposez HTTPS avec un TLS moderne et HSTS, envoyez des en-têtes de sécurité stricts (en particulier une Content Security Policy), hachez les mots de passe avec Argon2id derrière la MFA et la limitation de débit, utilisez des requêtes paramétrées et l'encodage des sorties, appliquez le contrôle d'accès côté serveur pour chaque objet, gardez les dépendances à jour et épinglées, fermez les ports inutilisés et journalisez les événements de sécurité de façon centralisée. Verrouillez d'abord le domaine et le DNS, car tout le reste suppose que vous contrôliez toujours votre nom de domaine.

Outils associés

HTTP Headers CheckSSL Certificate CheckPort CheckerDomain Health CheckerDMARC CheckerSubdomain FinderPassword Strength Tester

Articles associés

Chaîne de Certificats SSL ExpliquéeX-Frame-Options Explained: Fix “Refused to Connect” in an iframeErreur 429 Too Many Requests : causes et solutions complètesWHOIS nom de domaine : trouver le propriétaire et lire la fiche

Table des matières

  • Ce que recouvre vraiment la sécurité web
  • La pile de sécurité web : six couches à protéger
  • Couche 1 : verrouiller le domaine et le DNS
  • Couche 2 : HTTPS et TLS bien configurés
  • Couche 3 : en-têtes de sécurité HTTP
  • Couche 4 : une authentification qui résiste au credential stuffing
  • Sessions, cookies et CSRF
  • Injection et XSS : valider les entrées, encoder les sorties
  • Broken Access Control : le risque numéro un
  • Couche 5 : dépendances et chaîne d'approvisionnement logicielle
  • Couche 6 : durcissement du serveur (ports, correctifs, secrets, sauvegardes)
  • Authentification des e-mails : SPF, DKIM et DMARC
  • Journaliser, surveiller et anticiper l'intrusion
  • Tester : scanners, tests d'intrusion et contrôles continus
  • La checklist de sécurité web
  • Correspondance avec l'OWASP Top 10:2025
  • Questions fréquemment posées