X-Frame-Options est un en-tête de réponse HTTP qui indique au navigateur si votre page est autorisée à être affichée à l'intérieur d'un élément <iframe>, <frame> ou <object>. Son principal objectif est de prévenir les attaques de clickjacking, une catégorie d'attaques où un site malveillant intègre votre site de manière invisible et trompe les visiteurs pour qu'ils effectuent des actions non voulues.
Bien qu'il soit l'un des plus anciens en-têtes de sécurité (introduit vers 2009), X-Frame-Options reste largement déployé et offre toujours une protection importante. Voyons pourquoi il est important, comment il fonctionne, et ce que les propriétaires de sites WordPress doivent savoir.
Comment fonctionnent réellement les attaques de clickjacking
Le clickjacking est étonnamment simple dans son principe. Supposons que vous gériez un site WordPress avec un espace membre, et que la page de profil comporte un bouton « Supprimer mon compte ». Un attaquant crée une page qui ressemble à un quiz ou à un jeu amusant. Il intègre votre page de profil dans une iframe invisible positionnée directement au-dessus de son bouton « Cliquez ici pour voir votre résultat ».
Lorsque le visiteur clique sur ce qu'il pense être un bouton inoffensif sur la page de l'attaquant, il clique en réalité sur le bouton « Supprimer mon compte » de votre page cachée. Si le visiteur est connecté à votre site (et la plupart des navigateurs conservent les cookies de session), l'action aboutit. Le visiteur n'a aucune idée de ce qui vient de se passer.
Cette technique a été utilisée dans de réelles attaques pour :
- Modifier les paramètres de confidentialité sur des comptes de réseaux sociaux
- Autoriser des applications OAuth à l'insu de l'utilisateur
- Cliquer sur des publicités pour générer des revenus frauduleux
- Activer l'accès à la webcam ou au microphone dans les anciens navigateurs
- Transférer de l'argent dans les interfaces de banque en ligne
L'attaque fonctionne parce que le navigateur n'a aucun moyen intégré de savoir que l'iframe est utilisée de manière malveillante. X-Frame-Options offre à votre serveur un moyen de refuser entièrement d'être intégré dans une iframe.
Les valeurs de l'en-tête X-Frame-Options expliquées
L'en-tête prend en charge deux valeurs pratiques (plus une troisième dépréciée) :
DENY: la page ne peut être affichée dans aucune frame, sans exception. Aucun site web, y compris le vôtre, ne peut intégrer cette page dans une iframe. C'est le réglage le plus strict et il fonctionne bien pour les pages qui ne devraient jamais être intégrées, comme les pages de connexion ou les panneaux d'administration.SAMEORIGIN: la page ne peut être affichée dans une frame que si le site qui l'intègre a la même origine (même protocole, domaine et port). C'est la valeur la plus couramment utilisée car elle permet à votre propre site d'utiliser des iframes tout en bloquant les sites externes.ALLOW-FROM uri: ceci était censé vous permettre de spécifier une seule origine autorisée à intégrer votre page. Cependant, elle n'a jamais été prise en charge de manière cohérente par les navigateurs. Chrome et Safari ne l'ont jamais implémentée. Firefox l'a prise en charge un certain temps avant d'abandonner. Cette valeur est effectivement morte et ne devrait pas être utilisée.
Quand utiliser DENY ou SAMEORIGIN sur WordPress
Pour la plupart des sites WordPress, SAMEORIGIN est le bon choix. Voici pourquoi :
WordPress utilise lui-même des iframes en interne à plusieurs endroits. Le Customizer du thème charge un aperçu de votre site dans une iframe. Le téléverseur de la médiathèque utilise des iframes. La boîte de dialogue « Insérer un média » de l'éditeur classique aussi. Si vous définissez DENY, toutes ces fonctionnalités cesseront de fonctionner car même votre propre domaine ne sera pas autorisé à intégrer la page.
DENY est pertinent pour des pages spécifiques où l'intégration ne devrait jamais avoir lieu, comme une page de connexion autonome ou une page de traitement de paiement. Mais comme valeur par défaut à l'échelle du site WordPress, SAMEORIGIN offre la protection nécessaire sans casser les fonctionnalités d'administration.
Si vous utilisez une configuration WordPress headless où l'interface d'administration est sur un domaine et le front-end sur un autre, vous devrez être particulièrement vigilant ici, car SAMEORIGIN n'autorise l'intégration que depuis la même origine exacte.
Pourquoi ALLOW-FROM a été déprécié
La dépréciation de ALLOW-FROM mérite d'être comprise car elle illustre un point plus large concernant les en-têtes de sécurité web. La directive faisait partie de la spécification originale de X-Frame-Options, et l'idée était simple : permettre à un site de dire « seul ce domaine spécifique peut m'intégrer ». En pratique, elle présentait plusieurs problèmes :
- Elle n'acceptait qu'un seul URI, donc vous ne pouviez pas autoriser plusieurs domaines
- Chrome ne l'a jamais implémentée (le navigateur le plus utilisé au monde l'a simplement ignorée)
- Safari ne l'a jamais prise en charge non plus
- Le comportement était incohérent entre les navigateurs qui la prenaient en charge
La directive CSP frame-ancestors a été conçue comme le remplacement adéquat, prenant en charge plusieurs origines et offrant un comportement cohérent entre navigateurs. Si vous devez autoriser des domaines externes spécifiques à intégrer vos pages, frame-ancestors est la bonne solution.
X-Frame-Options vs. frame-ancestors de la CSP
La directive frame-ancestors de l'en-tête Content-Security-Policy remplit le même objectif que X-Frame-Options mais avec plus de flexibilité :
Content-Security-Policy: frame-ancestors 'self'C'est l'équivalent de X-Frame-Options: SAMEORIGIN. Mais frame-ancestors prend également en charge plusieurs origines :
Content-Security-Policy: frame-ancestors 'self' https://trusted-partner.com https://another-domain.comCela serait impossible avec X-Frame-Options seul.
Lorsque les deux en-têtes sont présents, le comportement du navigateur varie. Les navigateurs modernes privilégient généralement frame-ancestors par rapport à X-Frame-Options. Cependant, la pratique recommandée est d'envoyer les deux en-têtes pour une compatibilité maximale. Les anciens navigateurs qui ne comprennent pas la CSP utiliseront X-Frame-Options en repli, tandis que les navigateurs modernes utiliseront frame-ancestors.
Voici un exemple d'utilisation conjointe des deux :
X-Frame-Options: SAMEORIGIN
Content-Security-Policy: frame-ancestors 'self'Configurer X-Frame-Options pour WordPress
WordPress envoie en réalité X-Frame-Options: SAMEORIGIN par défaut pour la zone d'administration (wp-admin). Cela est fait dans le fichier wp-includes/functions.php via la fonction send_frame_options_header(). Cependant, le front-end de votre site ne reçoit pas cet en-tête par défaut.
Pour l'ajouter à l'échelle du site via Apache, placez ceci dans votre fichier .htaccess :
Header always set X-Frame-Options "SAMEORIGIN"Pour Nginx :
add_header X-Frame-Options "SAMEORIGIN" always;Vous pouvez aussi le définir via PHP dans votre thème ou une extension :
add_action('send_headers', function() {
header('X-Frame-Options: SAMEORIGIN');
});Si vous utilisez des extensions qui doivent intégrer votre site dans une iframe sur un autre domaine (certains outils de tests A/B, widgets de chat en direct ou services d'aperçu), vous devrez peut-être ajuster votre approche. Dans ce cas, utilisez frame-ancestors de la CSP pour autoriser ces domaines spécifiques au lieu de supprimer entièrement X-Frame-Options.
Ce que vérifie InspectWP
InspectWP vérifie si votre site WordPress envoie l'en-tête X-Frame-Options sur ses pages front-end. Si l'en-tête est absent, le rapport le signale comme un problème de sécurité car n'importe quel site web pourrait intégrer vos pages dans une iframe, ce qui pourrait permettre des attaques de clickjacking contre vos visiteurs. Le rapport indique également la valeur de l'en-tête s'il est présent, afin que vous puissiez vérifier qu'il est défini sur SAMEORIGIN ou DENY selon votre configuration.