Aller au contenu

Outil gratuit

Les en-têtes de sécurité de ce site

Une requête, et la liste de ce que votre serveur dit au navigateur. Le contrôle du HSTS et celui du contenu mixte sont dans la même page, parce qu'ils répondent à la même question : ce site est-il servi proprement ?

Sans inscription, sans e-mail à laisser. Vous pouvez coller une adresse complète : nous en extrayons le domaine.

Le mécanisme

Le serveur dit, le navigateur fait

Un en-tête de sécurité ne protège pas votre serveur : c'est une consigne envoyée au navigateur, qui l'applique chez le visiteur. Retirez-les une par une dans la réponse de gauche — la colonne de droite est ce qui se passe alors, chez lui.

Ce que le serveur répond

HTTP/2 200

  • Strict-Transport-Security: max-age=31536000; includeSubDomains
  • Content-Security-Policy: default-src 'self'
  • X-Frame-Options: DENY
  • Referrer-Policy: strict-origin-when-cross-origin
  • X-Content-Type-Options: nosniff

5 en-têtes sur 5 encore envoyés

Ce que le navigateur en fait

https://example.com

  • Un lien en http:// est réécrit en https:// par le navigateur lui-même, avant même que la requête parte.
  • Un script injecté depuis un autre domaine n'est pas exécuté, même s'il est bien présent dans la page.
  • La page refuse de s'afficher dans le cadre d'un autre site.
  • Le site visité ensuite reçoit votre nom de domaine, pas l'adresse complète de la page quittée.
  • Un fichier annoncé comme du texte reste du texte : le navigateur ne l'exécutera pas comme du script.

Ces consignes ne valent que pour les navigateurs qui les lisent, et seulement après une première réponse reçue : un en-tête ne remplace jamais une configuration serveur correcte. Les comportements décrits sont ceux des spécifications (HSTS : RFC 6797).

Ces en-têtes se perdent à la première mise en production

On les ajoute une fois, dans une configuration de serveur ou un fichier de règles. Puis un hébergeur migre le site, un module de cache se met devant, une extension réécrit les réponses, et ils disparaissent — sans qu'aucune page cesse de fonctionner. C'est exactement pour cela que personne ne le remarque. DomainVigil relit les en-têtes de vos sites en continu et vous écrit quand l'un d'eux tombe.

Ce qu'un contrôle automatique ne peut pas juger

La présence d'un en-tête se mesure ; la qualité d'une politique de sécurité du contenu ne se mesure pas. Une politique en douze directives qui autorise « unsafe-inline » protège moins qu'une politique en trois lignes qui ne l'autorise pas. Nous signalons ce cas parce qu'il est mécanique et fréquent. Pour le reste, une politique se relit — et se teste sur le site réel, en mode « report-only » d'abord.

Ce qui se perd

Un en-tête tombe. Rien ne casse.

Une migration d'hébergeur, un cache placé devant, une extension qui réécrit la réponse : la consigne n'est plus envoyée, et le site continue de fonctionner exactement pareil. C'est pour cela que personne ne le remarque.

  • HSTSstrict-transport-security
  • nosniffx-content-type-options
  • CSPcontent-security-policy

Lire le tableau

Sept en-têtes pesés, plus deux contrôles qui vont avec. Un en-tête vert est présent et correctement réglé ; le gris n'existe pas ici, un en-tête est là ou il n'est pas là.

strict-transport-security absent
Compté comme grave. Sans lui, un visiteur qui tape votre adresse sans « https » part en clair, et la redirection qui suit peut être détournée avant d'arriver. C'est le seul en-tête qui protège la première requête.
x-content-type-options absent
Compté comme grave, et c'est le plus simple à corriger : une seule valeur existe, « nosniff ». Sans elle, un fichier téléversé par un formulaire peut être interprété comme du HTML et exécuté dans le navigateur de vos visiteurs.
Les cinq autres, absents
Comptés en avertissement. Chacun ferme une porte précise, et aucun ne casse un site quand on l'ajoute — sauf la politique de sécurité du contenu, qui demande d'être testée avant d'être imposée.
x-frame-options absent mais CSP présent
Affiché en vert. La directive « frame-ancestors » de la politique de sécurité du contenu remplace cet en-tête et prend le pas sur lui dans les navigateurs modernes. Le déclarer en plus ne sert qu'aux très vieux navigateurs.
Le serveur annonce sa version
Un avertissement, pas une faille. « nginx/1.18.0 » dans une réponse indique à qui cherche exactement quelle liste de failles publiées essayer. La plupart des serveurs permettent de masquer cette ligne en une option.
Contenu mixte trouvé
Le navigateur bloque ces ressources sans rien afficher à l'utilisateur. Un script bloqué, et un formulaire ou un menu cesse de fonctionner sans message d'erreur. Trois exemples sont affichés pour que vous sachiez où chercher.

Les erreurs qui laissent un site mal servi

Aucune de ces cinq ne provoque d'erreur visible. C'est ce qui les rend durables.

  1. Le HSTS est déclaré, le http ne redirige pas

    Ce qui la provoque : Les deux réglages vivent dans deux endroits différents : la redirection dans les règles du serveur, l'en-tête dans la réponse https. On configure souvent le second et pas le premier.

    Le geste qui corrige : Le HSTS n'est lu qu'après une première connexion chiffrée. Sans redirection, cette première connexion n'a jamais lieu en https, et la protection ne démarre pas. Mettez la redirection en place d'abord.

  2. La politique de sécurité du contenu autorise « unsafe-inline »

    Ce qui la provoque : Le site a des scripts écrits directement dans les pages, ou un module qui en injecte. Interdire l'inline casse la page, alors on l'autorise pour que le site fonctionne.

    Le geste qui corrige : C'est la protection principale de cet en-tête qui disparaît. Passez par un nonce ou une empreinte pour les scripts que vous contrôlez, et testez en « Content-Security-Policy-Report-Only » avant d'imposer la politique.

  3. Les en-têtes disparaissent après l'ajout d'un cache ou d'un proxy

    Ce qui la provoque : Les en-têtes de sécurité sont émis par le serveur d'origine. Une couche placée devant peut les remplacer par les siens, ou ne pas les recopier.

    Le geste qui corrige : Contrôlez le site depuis l'extérieur, comme cette page le fait, et non depuis le serveur. C'est la réponse vue du dehors qui compte, et c'est la seule qui puisse mentir.

  4. Le HSTS est réglé sur une durée courte pour « voir si ça marche »

    Ce qui la provoque : Prudence légitime au premier jour, oubliée ensuite. La valeur reste à 300 ou 86 400 secondes pour toujours.

    Le geste qui corrige : Une durée courte expire entre deux visites d'un utilisateur occasionnel, qui repart en clair. Remontez à 31 536 000 secondes une fois la redirection vérifiée. C'est aussi le minimum exigé pour entrer dans la liste de préchargement des navigateurs.

  5. On ajoute « preload » sans en mesurer la portée

    Ce qui la provoque : Le mot se copie d'un exemple, il est accepté sans erreur, et la soumission à la liste se fait ensuite sans plus y penser.

    Le geste qui corrige : Un domaine préchargé est refusé en clair par les navigateurs, tous sous-domaines compris, et la sortie de la liste prend des mois. Vérifiez que chaque sous-domaine, y compris les environnements de test internes, est bien servi en https avant de le demander.

Les sept en-têtes, leur valeur recommandée et ce qu'elle empêche

Les valeurs ci-dessous sont celles que la spécification de chaque en-tête définit, ou celles qu'exige le programme de préchargement. Aucune n'est une préférence maison.

En-têteValeur recommandéeCe qu'elle empêche
strict-transport-securitymax-age=31536000; includeSubDomainsQu'un visiteur reparte en clair et se fasse intercepter la connexion. Un an est le minimum exigé par la liste de préchargement des navigateurs. « includeSubDomains » étend la règle à tous les sous-domaines, ce qui suppose qu'ils soient tous en https.
content-security-policydefault-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'L'exécution d'un script injecté, le chargement de ressources depuis un site que vous n'avez pas autorisé, et l'affichage de vos pages dans un cadre. À tester en « Content-Security-Policy-Report-Only » avant de l'imposer.
x-content-type-optionsnosniffQu'un fichier soit interprété autrement que ce que le serveur déclare. Sans lui, une image téléversée qui contient du HTML peut être exécutée comme une page. Une seule valeur existe.
x-frame-optionsDENY ou SAMEORIGINQu'un autre site affiche le vôtre dans un cadre invisible pour détourner les clics de vos visiteurs. Remplacé par « frame-ancestors » dans la politique de sécurité du contenu, qui prend le pas sur lui.
referrer-policystrict-origin-when-cross-originQue l'adresse complète de vos pages parte chez le site suivant. Un jeton ou un identifiant dans une URL fuit ainsi chez tous les tiers que la page charge.
permissions-policygeolocation=(), camera=(), microphone=()Qu'un script tiers chargé par votre page demande la caméra, le micro ou la position. La liste vide interdit la fonctionnalité à tout le monde, votre propre code compris.
cross-origin-opener-policysame-originQu'une fenêtre ouverte depuis votre site garde une référence utilisable vers la vôtre. C'est aussi la condition pour accéder aux mesures de temps précises dans le navigateur.

Trois en-têtes ne figurent pas dans ce tableau et sont pourtant lus par le contrôle : « server », « x-powered-by » et « x-aspnet-version ». Ils ne protègent rien, ils annoncent le logiciel et sa version. Les masquer se fait en une option de configuration.

Questions fréquentes

Quels en-têtes de sécurité sont vraiment indispensables ?

Deux, si vous n'en ajoutez que deux : « strict-transport-security », parce qu'il est le seul à protéger la première requête, et « x-content-type-options: nosniff », parce qu'il coûte une ligne et empêche un fichier téléversé d'être exécuté comme une page. Ensuite la politique de sécurité du contenu, qui est la plus puissante et la seule qui demande du travail.

Ajouter ces en-têtes peut-il casser mon site ?

Un seul le peut vraiment : la politique de sécurité du contenu, qui bloque ce qu'elle n'autorise pas. Testez-la en « Content-Security-Policy-Report-Only », qui signale sans bloquer, puis passez en mode strict. « strict-transport-security » avec « includeSubDomains » demande aussi de l'attention, car il s'applique à tous les sous-domaines, environnements internes compris.

Où ajoute-t-on un en-tête de sécurité ?

Dans la configuration du serveur web, ce qui est le plus fiable : « add_header » sous nginx, « Header always set » sous Apache, un bloc d'en-têtes dans un Caddyfile. Les couches placées devant fonctionnent aussi — règles de transformation chez Cloudflare, fichier « _headers » sur un hébergement statique. Évitez de les émettre depuis le code applicatif : une page servie par le cache sans passer par le code perdrait ses en-têtes.

Que veut dire « contenu mixte » ?

Une page servie en https qui charge une ressource en http — une image, un script, une feuille de style. Le navigateur bloque les scripts et les feuilles de style sans avertir l'utilisateur, et affiche un cadenas dégradé. Le symptôme classique est une fonctionnalité qui cesse de fonctionner sans message d'erreur. Ce contrôle lit la page d'accueil et affiche jusqu'à trois exemples.

Pourquoi le résultat parle-t-il d'une note sur sept ?

Parce que sept en-têtes sont pesés, un point par en-tête présent et correctement réglé. Ce n'est pas une note de sécurité : un site avec sept en-têtes parfaits et une extension percée reste vulnérable. C'est un décompte de ce qui est en place, rien de plus.

Mon site n'est pas joignable en https. Que dit l'outil ?

Qu'il n'a pas pu le joindre, et rien d'autre. Nous ne transformons pas une absence de réponse en « aucun en-tête de sécurité » : ce serait accuser un site que nous n'avons pas atteint. Le contrôle de la redirection http, lui, a tout de même lieu, et il vous dira si le site répond en clair.

Ce qu'on croit

Cinq certitudes que le contrôle dément

À gauche, ce qu'on se dit en relisant sa configuration. À droite, ce que montre la réponse réellement servie.

Le HSTS est en place, donc mes visiteurs arrivent en https.

Le HSTS n'est lu qu'après une première connexion chiffrée. Si le http ne renvoie pas vers le https, cette connexion n'a jamais lieu et la protection ne démarre pas.

Ma politique de sécurité du contenu fait douze directives, elle est donc solide.

Douze directives qui autorisent « unsafe-inline » protègent moins que trois qui ne l'autorisent pas. Le script injecté s'exécute quand même.

Les en-têtes sont dans la configuration du serveur, donc ils sont servis.

Une couche placée devant — cache, proxy, module — peut les remplacer par les siens ou ne pas les recopier. Seule la réponse vue du dehors fait foi.

Il manque x-frame-options, mes pages peuvent donc être affichées dans un cadre.

Si votre politique de sécurité du contenu porte « frame-ancestors », elle remplace cet en-tête et prend le pas sur lui dans les navigateurs modernes.

Sept en-têtes sur sept : le site est sécurisé.

C'est un décompte de ce qui est en place, pas une note de sécurité. Sept en-têtes parfaits et une extension percée laissent un site vulnérable.

La durée

Un an, écrit en secondes

31536000secondes

Le minimum pour entrer dans la liste de préchargement des navigateurs.

C'est le « max-age » d'un HSTS d'un an, et le minimum exigé pour figurer dans la liste préchargée par les navigateurs. En dessous de six mois, la protection expire entre deux visites d'un utilisateur occasionnel, qui repart en clair. La contrepartie du préchargement est lourde : un domaine préchargé est refusé en clair par les navigateurs, tous sous-domaines compris, et en sortir prend des mois.