Skip to main contentSkip to footer

En-têtes de sécurité

Les en-têtes de sécurité sont des lignes dans la réponse de votre serveur web qui indiquent au navigateur ce qu’il doit refuser : deviner les types de fichiers, afficher vos pages dans des cadres étrangers, transmettre des adresses complètes à d’autres sites, revenir à HTTP ou charger des scripts depuis des hôtes inconnus. Hive les définit pour vous, génère la configuration du serveur web correspondante et vérifie ce qui arrive réellement chez le visiteur. Cette page explique chaque en-tête, les trois voies qu’il peut prendre et que faire lorsque la vérification signale un problème.

Ce que comprend chaque formule

Tous les réglages d’en-têtes se trouvent sous Réglages de protection → Pare-feu et bots → En-têtes de sécurité. L’interrupteur principal Envoyer les en-têtes de sécurité est désactivé après l’installation ; la recommandation du démarrage rapide l’active. Les trois en-têtes de base font partie de l’extension gratuite. Les en-têtes avancés viennent avec le module Pro à partir de la formule Professional et fonctionnent aussi bien en Local Shield que dans le Community Network.

En-têteFormuleValeur après l’installation
X-Content-Type-OptionsGratuitnosniff
X-Frame-OptionsGratuitSAMEORIGIN
Referrer-PolicyGratuitstrict-origin-when-cross-origin
Strict-Transport-Security (HSTS)À partir de ProfessionalDésactivé ; la recommandation pour Professional l’active, sans preload
Permissions-PolicyÀ partir de Professionalgeolocation=(), camera=(), microphone=(), payment=(), usb=(), magnetometer=()
Content-Security-PolicyÀ partir de ProfessionalDésactivé, politique vide
Cross-Origin-Opener-Policy, -Resource-Policy, -Embedder-PolicyÀ partir de ProfessionalDésactivé

Chaque en-tête n’est envoyé que tant que Envoyer les en-têtes de sécurité est activé. Quand une formule prend fin, Hive cesse d’envoyer les en-têtes avancés et conserve les trois en-têtes de base. Les en-têtes que vous avez copiés dans la configuration du serveur web ne sont concernés par aucun des deux cas : le serveur continue de les envoyer jusqu’à ce que vous les retiriez.

Trois voies jusqu’au visiteur

Le bloc Comment les en-têtes atteignent vos visiteurs, au-dessus des lignes d’en-têtes, montre l’état de chaque voie sur votre site.

  1. Configuration du serveur web. nginx ou Apache ajoutent les en-têtes à chaque réponse : pages d’un cache, images, fichiers CSS et JavaScript, page de connexion et pages d’erreur. C’est la voie la plus compatible. Hive génère la configuration à partir de vos réglages.
  2. Protection étendue. Le pare-feu qui s’exécute avant WordPress (voir Pare-feu et WAF) envoie lui aussi les en-têtes. Il atteint les pages qu’une extension de cache livre via PHP, par exemple depuis advanced-cache.php. Il agit uniquement sur les requêtes du site public passant par index.php, pas dans wp-admin, et n’envoie HSTS qu’en HTTPS.
  3. WordPress seul. Hive ajoute les en-têtes à chaque page publique que WordPress construit. Les pages d’un cache, les fichiers statiques et tout ce que le serveur web répond lui-même partent sans eux.
Votre configurationVoie à utiliser
Pas de cache de pagesWordPress seul suffit. Activez les en-têtes et lancez la vérification.
Extension de cache qui sert les pages via PHP (WP Rocket, WP Super Cache, W3 Total Cache et d’autres dans leur configuration habituelle)Protection étendue, ou la configuration du serveur web
Cache servi par le serveur web sans PHP : Rocket-Nginx, règles de réécriture statiques dans le .htaccess, cache du panneau d’hébergementUniquement la configuration du serveur web
Vous voulez les en-têtes aussi sur les images, les fichiers et la page de connexionUniquement la configuration du serveur web
Hébergement sans accès à la configuration du serveurApache avec .htaccess : les lignes Apache ; sinon Protection étendue

Quel que soit votre choix, définissez chaque en-tête à un seul endroit. Un en-tête que le serveur web ajoute lui-même reste invisible pour WordPress, Hive ne peut donc pas l’omettre, et il arrive alors deux fois. La vérification des en-têtes le détecte.

Mise en place pas à pas

1

Activer les en-têtes

Ouvrez Réglages de protection → Pare-feu et bots → En-têtes de sécurité, activez Envoyer les en-têtes de sécurité et laissez les trois en-têtes de base sur leurs valeurs recommandées. Cliquez sur Enregistrer les modifications. Toutes les lignes d’en-têtes, interrupteur compris, se trouvent derrière Afficher les détails techniques ; le mode expert les ouvre d’office.

2

Ajouter les en-têtes avancés (module Pro)

Activez HTTP Strict Transport Security avec un max-age HSTS (secondes) de 300 pour les premiers jours. Comparez la Permissions-Policy avec les fonctions que votre site utilise. Mettez la Content-Security-Policy en mode Signaler seulement, comme décrit plus bas. Laissez les en-têtes Cross-Origin désactivés pour l’instant. Enregistrez.

3

Lancer la vérification des en-têtes

Ouvrez Configuration serveur et vérification des en-têtes et cliquez sur Vérifier les en-têtes de la page d’accueil. Si chaque ligne indique Arrive une fois, comme défini ici, la livraison est réglée. Tout autre résultat est expliqué dans La vérification des en-têtes.

4

Combler le manque sur les pages en cache

Si la vérification affiche Absent sur les pages en cache, activez la Protection étendue sous Serveur & maintenance → Serveur et vérifiez à nouveau. Si les en-têtes manquent toujours, votre cache livre les pages sans PHP ; passez à l’étape 5.

5

Confier les en-têtes au serveur web (facultatif)

Copiez les lignes générées pour nginx ou Apache dans la configuration du serveur et rechargez le serveur web. Désactivez ensuite Envoyer les en-têtes de sécurité dans Hive et enregistrez. Vérifiez à nouveau : chaque en-tête devrait maintenant afficher Défini par le serveur web ou une autre extension, ce qui est le bon résultat pour cette voie.

6

Augmenter HSTS et appliquer la CSP

Après quelques jours sans problème, portez le max-age HSTS à 31536000 (un an). Passez la Content-Security-Policy en mode Appliquer dès que la console du navigateur reste vide sur chaque type de page.

Chaque en-tête en détail

En-têteProtège contreRecommandéPeut casser
X-Content-Type-OptionsMIME sniffing : un fichier envoyé qui se fait passer pour une image est exécuté comme scriptActivé, nosniffPratiquement rien
X-Frame-OptionsClickjacking : un site étranger affiche votre page dans un cadre invisible et pousse les visiteurs à cliquerSAMEORIGINDENY bloque aussi les cadres entre vos propres pages ; toute valeur empêche l’intégration sur d’autres domaines
Referrer-PolicyFuite des chemins et paramètres de vos adresses vers d’autres sitesstrict-origin-when-cross-originno-referrer vous fait disparaître des statistiques de provenance des sites partenaires
Strict-Transport-SecurityRetour à HTTP et SSL stripping sur les réseaux ouverts300 pour tester, puis 31536000Toute page ou tout fichier encore chargé en HTTP ; avec includeSubDomains, tout sous-domaine sans certificat valide
Permissions-PolicyFonctions du navigateur utilisées par un script injectéDésactiver ce que vous n’utilisez pasRecherche de magasin (geolocation), Apple Pay et Google Pay (payment), appels vidéo (camera, microphone)
Content-Security-PolicyCross-site scripting et scripts injectésD’abord Signaler seulement, chaque service externe listé, puis AppliquerScripts du thème, suivi, outil de consentement, vidéos et cartes intégrées
Cross-Origin-Opener-PolicyAttaques via les fenêtres que vos pages ouvrent ou qui les ouvrentsame-origin si vous n’utilisez pas de fenêtres de connexion ou de paiement d’autres domainesFenêtres PayPal, Google et connexions sociales
Cross-Origin-Resource-PolicyD’autres sites qui chargent vos images et scripts dans leurs pagessame-origin seulement sans nom d’hôte CDNLiens directs et fichiers que vos pages chargent depuis un autre nom d’hôte à vous, comme un CDN
Cross-Origin-Embedder-PolicyNécessaire seulement pour des fonctions particulières du navigateur (SharedArrayBuffer, minuteurs précis)Désactivé, sauf demande d’un développeurLa plupart des contenus tiers intégrés : vidéos, cartes, polices web

À quoi ressemblent les en-têtes dans une réponse :

X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Referrer-Policy: strict-origin-when-cross-origin
Strict-Transport-Security: max-age=31536000; includeSubDomains
Permissions-Policy: geolocation=(), camera=(), microphone=(), payment=(), usb=()
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Resource-Policy: same-origin

HSTS. Une fois qu’un navigateur a vu l’en-tête, il ne se connecte plus qu’en HTTPS pendant la durée indiquée par max-age, et vous ne pouvez pas revenir en arrière pour les visiteurs qui l’ont déjà reçu. Ne l’activez que lorsque chaque page et chaque fichier se chargent en HTTPS. La valeur enregistrée par défaut est 63072000 (deux ans), qui est aussi la limite haute ; commencez avec 300 (cinq minutes). HSTS includeSubDomains étend la règle à chaque sous-domaine, y compris ceux de la messagerie et de la boutique. HSTS preload demande aux navigateurs d’inscrire votre domaine dans leur liste intégrée (hstspreload.org) ; il exige includeSubDomains et au moins un an, et sortir de la liste prend des mois. Hive n’envoie HSTS qu’en HTTPS. Derrière un proxy qui termine TLS, WordPress doit reconnaître la requête comme HTTPS, sinon Hive omet HSTS.

Permissions-Policy. feature=() désactive une fonction, feature=(self) l’autorise pour vos propres pages uniquement. La valeur par défaut désactive payment ; une boutique avec des boutons Apple Pay ou Google Pay a besoin de payment=(self) ou doit retirer l’entrée, sinon les boutons n’apparaissent pas.

X-Frame-Options et la CSP. Les navigateurs actuels suivent d’abord la directive frame-ancestors d’une Content-Security-Policy appliquée. X-Frame-Options reste pour les anciens navigateurs ; gardez les deux cohérents, par exemple SAMEORIGIN et frame-ancestors 'self'.

La Content-Security-Policy pas à pas

Une CSP est une liste de sources depuis lesquelles le navigateur peut charger scripts, styles, images, polices, cadres et connexions. Tout le reste est refusé. C’est l’en-tête le plus fort et celui qui casse le plus, c’est pourquoi il a deux modes : Signaler seulement envoie la politique comme Content-Security-Policy-Report-Only, rien n’est bloqué et chaque violation apparaît dans la console du navigateur. Appliquer envoie Content-Security-Policy et bloque.

  1. Commencer avec la politique de départ WordPress. Réglez Mode Content-Security-Policy sur Signaler seulement et collez la politique ci-dessous dans Content-Security-Policy. Elle convient à un site WordPress sans service externe. La plupart des thèmes ont besoin de 'unsafe-inline' pour les scripts et les styles, il est donc inclus.
  2. Ouvrir chaque type de page. Page d’accueil, un article, une page, le formulaire de contact, la boutique, le panier et la caisse, avec la bannière de cookies acceptée, car le suivi et les contenus intégrés ne se chargent souvent qu’après le consentement. Ouvrez la console du navigateur avec F12 ; chaque source que la politique n’autorise pas y figure avec la directive enfreinte.
  3. Ajouter chaque source externe à sa directive. Un hôte de scripts va dans script-src, un hôte auquel la page envoie des données dans connect-src, un cadre vidéo ou carte dans frame-src, un hôte de polices dans font-src. Séparez les directives par des points-virgules et les hôtes par des espaces. Enregistrez, rechargez et recommencez jusqu’à ce que la console reste vide.
  4. Passer en mode Appliquer. Réglez le mode sur Appliquer, ouvrez encore une fois les types de page et surveillez les formulaires et la caisse pendant quelques jours.

La politique de départ WordPress fournie par l’extension :

default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self'; frame-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'self'

Exemple : Google Tag Manager avec Google Analytics 4. Le gestionnaire de balises charge son script depuis www.googletagmanager.com, et Analytics envoie ses mesures à deux familles d’hôtes Google. Ajoutez-les à script-src et connect-src :

default-src 'self'; script-src 'self' 'unsafe-inline' https://www.googletagmanager.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' https://*.google-analytics.com https://*.analytics.google.com; frame-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'self'

Chaque balise supplémentaire du conteneur apporte ses propres hôtes, que la console nomme. Dans la politique de départ, img-src autorise déjà les images de tout hôte HTTPS, les pixels de suivi n’y demandent donc aucune entrée. En mode Signaler seulement, les navigateurs ignorent frame-ancestors ; X-Frame-Options prend le relais jusqu’à ce que vous appliquiez la politique.

URI de rapport CSP. Facultative. Une adresse HTTPS qui reçoit chaque violation sous forme de rapport JSON. Hive l’envoie comme report-uri et, pour les navigateurs actuels, comme report-to csp-endpoint avec un en-tête Reporting-Endpoints :

Content-Security-Policy-Report-Only: default-src 'self'; ...; report-uri https://example.com/csp-report; report-to csp-endpoint
Reporting-Endpoints: csp-endpoint="https://example.com/csp-report"

Protection des données : chaque rapport contient l’adresse IP du visiteur et l’adresse qu’il a consultée. Un service de rapport externe traite donc des données personnelles pour votre compte, nécessite un contrat de sous-traitance et doit figurer dans votre politique de confidentialité. Pour la plupart des sites, la console du navigateur pendant la phase de signalement suffit ; laissez alors le champ vide.

La configuration du serveur web générée

Sous Configuration serveur et vérification des en-têtes, Hive affiche la configuration pour nginx et pour Apache, construite à partir des réglages enregistrés, chacune avec un bouton Copier. Enregistrez d’abord après une modification. Quand Envoyer les en-têtes de sécurité est désactivé, il n’y a rien à générer : activez, enregistrez, copiez, puis désactivez à nouveau une fois la configuration active. Gardez une copie des lignes, car chaque modification ultérieure demande les mêmes étapes. Avec les trois en-têtes de base et HSTS, le résultat ressemble à ceci :

# ReportedIP Hive: security headers for nginx.
# Paste into the server { } block that serves HTTPS, then run: nginx -t && systemctl reload nginx
# A location { } block with its own add_header inherits none of these lines.
# Repeat them there, or keep them in one file and include it in both places.
# Afterwards switch off "Send security headers" in Hive, otherwise every header is sent twice.
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Strict-Transport-Security "max-age=31536000" always;
# ReportedIP Hive: security headers for Apache (.htaccess or virtual host).
# Afterwards switch off "Send security headers" in Hive, otherwise every header is sent twice.
<IfModule mod_headers.c>
	Header always set X-Content-Type-Options "nosniff"
	Header always set X-Frame-Options "SAMEORIGIN"
	Header always set Referrer-Policy "strict-origin-when-cross-origin"
	Header always set Strict-Transport-Security "max-age=31536000" "expr=%{HTTPS} == 'on'"
</IfModule>

Les points à surveiller :

  • always. Sans ce mot, nginx n’ajoute les en-têtes qu’aux réponses réussies. Avec lui, ils atteignent aussi les pages d’erreur et les redirections.
  • Les blocs location n’héritent pas. nginx ne transmet les lignes add_header qu’aux blocs qui n’en ont aucune. Un bloc location qui définit son propre en-tête, typiquement Cache-Control pour les images ou le bloc de cache de Rocket-Nginx, perd tous les en-têtes de sécurité. Placez les lignes dans un fichier et incluez-le dans le bloc server et dans chacun de ces blocs location.
  • Bloc server HTTPS. Les lignes nginx vont dans le bloc qui sert le port 443. Un bloc qui ne fait que rediriger HTTP vers HTTPS n’en a pas besoin.
  • Tester avant de recharger. nginx -t vérifie la syntaxe ; ne rechargez que s’il signale un succès.
  • IfModule sur Apache. Si mod_headers manque, Apache ignore le bloc au lieu de répondre à chaque requête par une erreur 500. La vérification affiche alors les en-têtes comme absents, et l’hébergeur doit activer le module.
  • HSTS sur Apache. La condition expr=%{HTTPS} == 'on' limite HSTS à HTTPS, les mêmes lignes fonctionnent donc dans un .htaccess qui sert les deux protocoles.
  • Désactiver ensuite « Envoyer les en-têtes de sécurité ». Sinon WordPress ajoute chaque en-tête une seconde fois aux pages qu’il construit.

Le fichier à inclure pour nginx, à titre d’exemple :

# /etc/nginx/snippets/security-headers.conf holds the generated add_header lines
server {
    listen 443 ssl;
    server_name example.com;
    include snippets/security-headers.conf;

    location ~* \.(css|js|jpg|jpeg|png|webp|svg|woff2)$ {
        add_header Cache-Control "public, max-age=2592000";
        include snippets/security-headers.conf;
    }
}

La vérification des en-têtes

Vérifier les en-têtes de la page d’accueil charge la page d’accueil de votre site trois fois depuis le serveur lui-même : deux fois comme un visiteur, pour que la seconde requête soit servie par un éventuel cache de pages, et une fois avec un paramètre supplémentaire qui contourne le cache. Elle compare ensuite ce qui arrive avec vos réglages. Seule votre propre adresse est demandée ; rien n’est envoyé à reportedip.com. La vérification couvre la page d’accueil ; pour d’autres pages, des fichiers ou la page de connexion, utilisez l’onglet réseau des outils du navigateur, curl -sI https://example.com/ ou l’outil gratuit Security Headers.

RésultatSignificationQue faire
Arrive une fois, comme défini iciL’en-tête arrive exactement une fois avec votre valeur, sur la page en cache comme sur la page hors cache.Rien.
Absent sur les pages en cacheWordPress envoie l’en-tête, mais le cache de pages livre les pages sans lui.Activez la Protection étendue. Si elle est déjà active, votre cache fonctionne sans PHP : utilisez la configuration du serveur web.
Absent sur toutes les pagesHive prévoit l’en-tête, mais il n’arrive ni depuis le cache ni hors cache. Quelque chose entre WordPress et le visiteur le retire, comme un proxy, un CDN ou la configuration de l’hébergement, ou la page d’accueil ne vient pas du tout de WordPress.Définissez l’en-tête dans la configuration du serveur web et cherchez dans le CDN ou le proxy des règles qui retirent des en-têtes de réponse.
Envoyé deux fois, par le serveur web et iciLe même en-tête arrive plusieurs fois, généralement parce que le serveur web ou l’hébergement le définit et que Hive l’envoie aussi. Les navigateurs utilisent alors l’une des valeurs ou appliquent les deux, ce qui est rarement voulu.Gardez une seule source : retirez l’en-tête du serveur ou désactivez-le ici. Une fois tout confié au serveur, désactivez Envoyer les en-têtes de sécurité.
Une autre valeur arrive, le serveur web ou une extension la définitUne valeur arrive, mais pas la vôtre. Le serveur web, l’hébergement, un CDN ou une autre extension définit l’en-tête et l’emporte.Trouvez l’autre source et décidez où l’en-tête doit vivre. Modifiez ou retirez la valeur à cet endroit.
Défini par le serveur web ou une autre extensionHive ne prévoit pas cet en-tête, parce qu’il est désactivé ici ou ne fait pas partie de votre formule, mais il arrive.Attendu après avoir confié les en-têtes au serveur web. Vérifiez que la valeur est celle que vous voulez.

Deux autres messages peuvent apparaître à la place du tableau :

  • « Aucun en-tête de sécurité n’arrive sur la page d’accueil, ni de WordPress ni du serveur web. » Rien n’est défini nulle part. Activez Envoyer les en-têtes de sécurité et enregistrez, ou vérifiez que votre configuration serveur est active.
  • « La page d’accueil n’a pas pu être chargée » avec un message d’erreur. Le serveur n’atteint pas sa propre adresse : une protection par mot de passe sur un site de préproduction, un pare-feu de l’hébergeur qui bloque les requêtes du serveur vers lui-même, ou un domaine qui pointe ailleurs. Vérifiez alors les en-têtes depuis l’extérieur avec les outils cités plus haut.

Le registre de État du système affiche la suggestion Les pages en cache n’ont pas les en-têtes de sécurité quand les en-têtes sont activés, qu’un cache de pages est actif et que la Protection étendue ne tourne pas. Elle disparaît dès que la Protection étendue tourne. Si vous utilisez la configuration du serveur web et avez désactivé Envoyer les en-têtes de sécurité, elle n’apparaît pas.

Dépannage

Un en-tête arrive deux fois alors que je ne l’ai défini que dans Hive

L’hébergement le définit donc aussi. Les endroits fréquents sont les options de sécurité ou SSL du panneau d’hébergement (un interrupteur HSTS est courant), un .htaccess écrit par une autre extension ou par l’hébergeur, le champ des directives nginx du panneau et des règles CDN qui ajoutent des en-têtes. Cherchez le nom de l’en-tête à ces endroits, gardez une seule source et relancez la vérification.

La vérification affiche « Absent sur les pages en cache » alors que la Protection étendue est active

Votre cache de pages livre les fichiers sans PHP, par exemple Rocket-Nginx, des règles de réécriture statiques ou un cache serveur de l’hébergeur. Seule la configuration du serveur web atteint ces pages. Avec Rocket-Nginx, incluez aussi le fichier d’en-têtes dans ses blocs location de cache, car ils définissent leurs propres en-têtes.

Après la modification, les pages en cache affichent encore les anciennes valeurs

Selon l’extension, un cache de pages enregistre les en-têtes avec la page au moment où il crée le fichier de cache. Videz le cache de pages et celui du CDN après chaque changement d’en-tête, puis vérifiez à nouveau.

Où placer les lignes dans un panneau d’hébergement ?

Les lignes Apache vont dans le .htaccess du dossier WordPress, au-dessus du bloc WordPress. Les panneaux avec nginx proposent en général un champ de directives nginx supplémentaires par domaine (dans Plesk sous les réglages Apache et nginx, dans ISPConfig dans l’onglet Options) ; collez-y les lignes add_header. Certains panneaux placent ce champ dans un bloc location, lancez donc la vérification ensuite. Sur un hébergement mutualisé sans ces deux possibilités, utilisez la Protection étendue.

Les boutons de paiement, la carte ou la vidéo ont disparu

Regardez la console du navigateur. Une violation CSP nomme l’hôte bloqué : ajoutez-le à la directive correspondante. Un bouton Apple Pay ou Google Pay absent renvoie à payment=() dans la Permissions-Policy, une recherche de magasin sans position à geolocation=(). Si des contenus intégrés cassent après l’activation de Cross-Origin-Embedder-Policy, l’en-tête doit être désactivé à nouveau.

Un sous-domaine n’est plus joignable

HSTS avec includeSubDomains impose HTTPS sur chaque sous-domaine. Un sous-domaine sans certificat valide reste injoignable pour chaque visiteur qui a vu l’en-tête, jusqu’à l’expiration du max-age. Donnez un certificat au sous-domaine, et désactivez includeSubDomains si ce n’est pas possible.

Les en-têtes manquent dans wp-admin et sur la page de connexion

C’est voulu : WordPress et la Protection étendue n’ajoutent les en-têtes qu’aux pages publiques. La configuration du serveur web couvre aussi wp-admin et la page de connexion.

Dernière mise à jour: · Maintenu par l’équipe ReportedIP

Security Focused
Conforme au RGPD
Made in Germany
Retour aux docs