Sécurité
Que sont les en-têtes de sécurité ? Le rôle de chacun et comment les ajouter
Les en-têtes de sécurité activent des protections intégrées à tous les navigateurs. Le rôle de chacun, des valeurs de départ sûres et la façon de les ajouter sur les serveurs et plateformes courants.
Sur cette page
Les en-têtes de sécurité sont des en-têtes de réponse HTTP qui demandent au navigateur d'activer des protections dont il dispose déjà : ne se connecter qu'en HTTPS, refuser d'exécuter des scripts venus d'endroits inattendus, interdire aux autres sites d'afficher la page dans un cadre, etc. Ils ne corrigent pas un code vulnérable, mais ils rendent plusieurs attaques courantes, comme le cross-site scripting, le détournement de clic (clickjacking) ou la rétrogradation de protocole, bien plus difficiles à réussir, ou moins dommageables lorsqu'elles aboutissent.
Comment voir les en-têtes envoyés par votre site
- Dans le navigateur : ouvrez les outils de développement, allez dans l'onglet Réseau, rechargez la page, cliquez sur la première requête (le document) et consultez les en-têtes de réponse.
- Depuis un terminal :
curl -I https://example.comaffiche les en-têtes. - Avec un outil de vérification : l'outil gratuit de vérification de la sécurité de Rudra contrôle que le site utilise HTTPS et y redirige le HTTP simple, que le certificat TLS est valide et loin d'expirer, puis lit la valeur des en-têtes HSTS, Content-Security-Policy, X-Frame-Options (ou de la directive CSP
frame-ancestors), X-Content-Type-Options, Referrer-Policy et Permissions-Policy. Il signale aussi les en-têtesServerouX-Powered-Byqui révèlent des numéros de version, et vérifie les attributs des cookies ainsi que la configuration CORS.
La seule présence d'un en-tête ne suffit pas à conclure. Une Content-Security-Policy qui autorise les scripts de n'importe quelle provenance est bien présente, mais ne protège presque rien. C'est pourquoi Rudra analyse aussi les valeurs : un max-age HSTS inférieur à 180 jours, une CSP contenant 'unsafe-inline' ou un * dans script-src, ou encore une valeur X-Frame-Options invalide sont signalés comme faibles. Les sections ci-dessous vous aideront à évaluer vos propres valeurs.
Les en-têtes, un par un
Strict-Transport-Security (HSTS)
Il demande au navigateur d'utiliser HTTPS pour votre domaine pendant une durée donnée, même si quelqu'un saisit http:// ou suit un ancien lien. Il referme ainsi la fenêtre pendant laquelle un attaquant présent sur le réseau pourrait intercepter la première requête non sécurisée. Une valeur courante est Strict-Transport-Security: max-age=63072000; includeSubDomains (deux ans).
- Commencez par un
max-agecourt, par exemple 300 secondes, et augmentez-le une fois certain que toutes les pages fonctionnent en HTTPS. - N'ajoutez
includeSubDomainsque si tous les sous-domaines sont servis en HTTPS, y compris les anciens que vous avez peut-être oubliés. - L'option
preload, associée à l'inscription sur la liste de préchargement des navigateurs, inscrit en dur le HTTPS pour votre domaine dans les navigateurs. Revenir en arrière est long et difficile : ajoutez-la en dernier, en connaissance de cause. - Les navigateurs ne tiennent compte de HSTS que s'il est reçu en HTTPS.
Content-Security-Policy (CSP)
C'est la liste des emplacements depuis lesquels la page peut charger des scripts, des styles, des images, des polices et des cadres. Si un attaquant parvient à injecter un script, une bonne CSP empêche le navigateur de l'exécuter. C'est l'en-tête le plus puissant de cette liste, et celui qu'il est le plus facile de mal configurer. Un point de départ raisonnable pour un site simple :
Content-Security-Policy: default-src 'self'; img-src 'self' data:; object-src 'none'; base-uri 'self'; frame-ancestors 'none'
Cette politique n'autorise que les ressources de votre propre origine (plus les images data: intégrées), bloque les plugins, empêche une balise <base> injectée de détourner les URL relatives et interdit l'affichage dans un cadre. Les sites réels utilisent des outils de mesure d'audience, des polices, des contenus intégrés et des prestataires de paiement, qu'il faut tous autoriser explicitement, et les scripts en ligne sont bloqués à moins de les autoriser par un nonce ou un hash. Déployez-la d'abord avec Content-Security-Policy-Report-Only : le navigateur signale les violations dans la console (et à un point de collecte des rapports si vous en avez défini un) sans rien bloquer, ce qui vous permet d'ajuster la politique avant de l'appliquer.
X-Content-Type-Options
X-Content-Type-Options: nosniff empêche les navigateurs de deviner le type d'un fichier et, par exemple, d'exécuter comme un script un fichier texte téléversé. Il ne se configure pas et ne casse presque jamais rien, à condition que votre serveur envoie des en-têtes Content-Type corrects. Ajoutez-le partout.
Protection contre le clickjacking : frame-ancestors et X-Frame-Options
Le clickjacking, ou détournement de clic, amène les internautes à cliquer sur un élément de votre site alors que celui-ci est dissimulé dans un cadre affiché par un autre site. Le mécanisme moderne est la directive CSP frame-ancestors 'none' (aucun affichage dans un cadre) ou frame-ancestors 'self' (vos propres pages uniquement). L'ancien en-tête X-Frame-Options: DENY ou SAMEORIGIN remplit le même rôle dans les navigateurs plus anciens, et envoyer les deux ne pose aucun problème. Si vos pages doivent être intégrées sur des sites partenaires précis, indiquez ces origines dans frame-ancestors.
Referrer-Policy
Il détermine quelle part de l'URL courante est transmise aux autres sites lorsqu'un visiteur suit un lien ou charge une ressource. Les URL peuvent contenir des termes de recherche, des identifiants ou des jetons que vous ne voulez pas voir fuiter. Referrer-Policy: strict-origin-when-cross-origin envoie l'URL complète à l'intérieur de votre site, mais seulement l'origine (https://example.com) aux autres sites, et rien du tout lors d'un passage de HTTPS à HTTP. Les navigateurs modernes appliquent déjà cette valeur par défaut ; la définir explicitement rend le comportement homogène.
Permissions-Policy
Il désactive les fonctionnalités sensibles du navigateur dont votre site ne se sert pas, afin que ni votre code ni un service tiers intégré ne puissent les demander. Pour un site qui n'a besoin ni de la caméra, ni du micro, ni de la géolocalisation : Permissions-Policy: camera=(), microphone=(), geolocation=().
Les en-têtes à supprimer ou à laisser de côté
- Les en-têtes qui révèlent une version. Des valeurs
ServeretX-Powered-Byassorties de numéros de version indiquent précisément aux attaquants quel logiciel et quelle version viser. Supprimez-les ou retirez la version (sous nginx,server_tokens off;). - X-XSS-Protection pilotait un filtre que les navigateurs modernes ont supprimé. Ne comptez pas dessus : omettez-le ou réglez-le sur
0.
Comment ajouter des en-têtes de sécurité
nginx
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;add_header X-Content-Type-Options "nosniff" always;add_header Referrer-Policy "strict-origin-when-cross-origin" always;add_header X-Frame-Options "DENY" always;
Le paramètre always ajoute aussi l'en-tête aux réponses d'erreur. Attention à l'héritage : dès qu'un bloc location contient une directive add_header, il n'hérite plus de celles définies au niveau server, et les en-têtes disparaissent sans prévenir de ces URL. Répétez-les, ou regroupez-les dans un fichier commun que vous chargez avec include.
Apache
Une fois mod_headers activé, dans l'hôte virtuel ou le fichier .htaccess : Header always set X-Content-Type-Options "nosniff", puis le même modèle pour chaque en-tête, par exemple Header always set Referrer-Policy "strict-origin-when-cross-origin".
Next.js
Dans next.config.js, renvoyez les en-têtes pour tous les chemins : async headers() { return [{ source: '/:path*', headers: [{ key: 'X-Content-Type-Options', value: 'nosniff' }, { key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' }] }]; }. Pour une CSP avec nonces, générez plutôt l'en-tête à chaque requête dans le middleware, comme le décrit la documentation de Next.js.
Netlify, Cloudflare Pages et hébergeurs similaires
Ces hébergeurs lisent un fichier _headers placé dans votre dossier de publication. Écrivez un motif de chemin sur une ligne, par exemple /*, puis chaque en-tête sur sa propre ligne indentée en dessous, par exemple X-Content-Type-Options: nosniff. Sur Vercel, l'équivalent est la section headers du fichier vercel.json. Si vous utilisez un CDN, celui-ci peut généralement ajouter des en-têtes lui aussi.
Les déployer sans risque
- Ajoutez d'abord les en-têtes à faible risque :
X-Content-Type-Options,Referrer-Policy,Permissions-Policyet la protection contre le clickjacking. - Activez HSTS avec un
max-agecourt, puis augmentez-le sur quelques semaines. - Déployez la CSP en mode report-only, corrigez ce qu'elle signale, puis appliquez-la.
- Testez les parcours qui font intervenir des tiers : connexion, tunnel de commande et cadres de paiement, vidéos intégrées, cartes, widgets de chat et outils de mesure d'audience.
- Relancez l'outil de vérification de la sécurité, puis recommencez chaque fois que vous ajoutez un nouvel outil tiers.
Les erreurs courantes
- Copier la CSP stricte d'un autre site et casser les paiements, la mesure d'audience ou les contenus intégrés.
- Écrire une CSP truffée de
'unsafe-inline', de'unsafe-eval'et de jokers, qui réussit un contrôle de présence mais protège peu. - Ajouter l'option HSTS
preloadavant que tous les sous-domaines soient prêts pour HTTPS. - Définir des en-têtes dans une balise HTML
<meta>. Seules certaines directives CSP fonctionnent ainsi ; HSTS,frame-ancestorsetX-Frame-Optionssont ignorés dans les balises meta. - Ajouter les en-têtes à la fois dans l'application et dans le proxy, si bien que les réponses portent des valeurs en double ou contradictoires.
- Considérer les en-têtes comme un substitut à la mise à jour des logiciels, à la validation des entrées et à l'échappement des sorties.
Ce que les en-têtes, et leur vérification, ne couvrent pas
Les en-têtes ne constituent qu'une couche de protection. Leur vérification ne détectera ni une extension obsolète, ni un mot de passe administrateur faible, ni une faille d'injection, ni un fichier de sauvegarde exposé. Les cookies méritent eux aussi un examen à part : les cookies de session doivent porter les attributs Secure, HttpOnly et SameSite. L'outil de vérification de la sécurité de Rudra indique ces attributs pour les cookies déposés par la réponse de la page elle-même (par leur nom, jamais par leur valeur) ; consultez comment vérifier la sécurité des cookies pour le détail, et comment vérifier la sécurité d'un site web pour savoir ce qu'un contrôle passif peut vous apprendre ou non. Pour une vue plus large de la santé de votre site, lancez un audit de site web complet.
Questions fréquentes
Quel en-tête de sécurité ajouter en premier ?
Assurez-vous que tout le site est servi en HTTPS, puis ajoutez X-Content-Type-Options: nosniff, une Referrer-Policy et une protection contre le clickjacking, qui ne cassent presque jamais rien. Ajoutez ensuite HSTS avec un max-age court, et terminez par Content-Security-Policy, d'abord en mode report-only.
Les en-têtes de sécurité ont-ils un effet sur le SEO ?
Pas directement. Le HTTPS lui-même est un signal de classement léger pour Google, mais des en-têtes comme CSP ou X-Content-Type-Options n'influencent pas le classement. Ils protègent vos visiteurs et la réputation de votre site, ce qui compte davantage.
X-Frame-Options est-il obsolète ?
Il a été supplanté par la directive CSP frame-ancestors, plus souple. Envoyer les deux est sans danger et permet de couvrir encore les anciens navigateurs.
Peut-on définir des en-têtes de sécurité avec une balise meta ?
En partie seulement. Une Content-Security-Policy peut être définie dans une balise meta, mais sans frame-ancestors ni envoi de rapports. HSTS, X-Frame-Options et la plupart des autres en-têtes de sécurité ne fonctionnent que sous forme de véritables en-têtes de réponse HTTP.
Une Content-Security-Policy stricte risque-t-elle de casser mon site ?
Oui, si elle bloque des scripts, des styles ou des cadres dont vos pages ont besoin. C'est pourquoi il faut commencer par Content-Security-Policy-Report-Only, examiner les violations signalées, ajuster la politique et ne l'appliquer qu'ensuite.