# Protection anti-clickjacking quand vous ne pouvez pas poser de header CSP (/fr/blog/frame-ancestors-without-csp-header)



La protection anti-clickjacking a besoin d'un vrai header de réponse HTTP. La directive de la politique de sécurité du contenu (CSP) qui contrôle qui peut placer votre page dans une frame, [`frame-ancestors`](/fr/docs/web-security/policies/content-security-policy/directives/frame-ancestors), est silencieusement ignorée quand la politique provient d'une balise `<meta>`, si bien qu'une CSP livrée en meta ne vous donne aucune protection contre le framing. Si vous ne pouvez pas poser des headers librement, le repli limité par l'hébergeur est `X-Frame-Options`, plus simple et plus contraint. Cet article explique la faille de la balise meta, ce que `X-Frame-Options` peut et ne peut pas faire, et vers quoi vous tourner quand vos seules options sont des headers limités ou une balise meta.

## frame-ancestors est ignoré dans une balise meta [#frame-ancestors-est-ignoré-dans-une-balise-meta]

`frame-ancestors` décide quelles origines peuvent embarquer votre page dans une frame, ce qui est votre défense contre le clickjacking (un attaquant qui embarque votre page de façon invisible et pousse un utilisateur à cliquer au travers). Cela fonctionne quand la politique arrive via le header de réponse `Content-Security-Policy`. Cela ne fonctionne **pas** depuis une balise meta.

La spécification CSP liste `frame-ancestors` parmi les directives ignorées quand la politique est livrée dans un élément `<meta http-equiv>`. Le navigateur conserve le reste de la politique meta et écarte discrètement cette directive. Aucune erreur de console ne vous indique que la page est sans protection, et c'est ce qui rend la chose dangereuse : la politique semble présente, mais la règle de framing a disparu.

```html
<!-- frame-ancestors here is silently ignored, no clickjacking protection -->
<meta http-equiv="Content-Security-Policy" content="frame-ancestors 'none'">
```

C'est l'une des rares directives qui ne fonctionnent qu'en header. La liste complète et le raisonnement sont dans [balise meta CSP contre header HTTP](/fr/blog/csp-meta-tags-vs-headers). Pour le clickjacking, la conclusion est étroite et absolue : si vous ne pouvez émettre qu'une balise meta, vous ne pouvez pas utiliser `frame-ancestors`, et il vous faut un mécanisme différent.

## X-Frame-Options, le repli limité par l'hébergeur [#x-frame-options-le-repli-limité-par-lhébergeur]

Quand vous ne pouvez pas poser de header CSP mais pouvez poser certains headers de réponse, [`X-Frame-Options`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options) est l'ancien header qui contrôle le framing. Certains hébergeurs et CDN exposent une courte liste de headers de sécurité autorisés même quand ils ne vous laissent pas définir une CSP arbitraire, et `X-Frame-Options` figure souvent sur cette liste. Il a deux valeurs utilisables :

```http
X-Frame-Options: DENY
```

```http
X-Frame-Options: SAMEORIGIN
```

`DENY` empêche tout site, y compris le vôtre, de placer la page dans une frame. `SAMEORIGIN` n'autorise que votre propre origine à la framer. C'est tout son vocabulaire. Le header est grossier à dessein, ce qui est à la fois sa limite et la raison pour laquelle il fonctionne encore comme repli.

Les contraintes comptent :

* **Pas d'allowlist de plusieurs origines.** `frame-ancestors` peut nommer plusieurs embarqueurs de confiance (`frame-ancestors 'self' https://partner.example`). `X-Frame-Options` ne le peut pas. Vous avez soit la même origine, soit personne, et aucun moyen d'autoriser un partenaire nommé.
* **`ALLOW-FROM` est déprécié et ne fonctionne pas.** L'ancienne valeur `X-Frame-Options: ALLOW-FROM https://partner.example` était censée autoriser un seul embarqueur externe. Les navigateurs modernes l'ignorent. Ne comptez pas dessus ; si vous devez autoriser un partenaire précis à vous framer, cela exige `frame-ancestors`, qui exige un vrai header.
* **`frame-ancestors` le supplante.** Quand une page envoie les deux, les navigateurs honorent la directive CSP et ignorent `X-Frame-Options` (voyez [X-Frame-Options contre frame-ancestors](/fr/blog/x-frame-options-vs-frame-ancestors) pour la comparaison complète). `X-Frame-Options` est donc le repli que vous utilisez uniquement quand `frame-ancestors` ne vous est pas accessible.

Pour le comportement propre de la directive, sa syntaxe, et son rapport détaillé avec le header hérité, voyez la [référence de la directive frame-ancestors](/fr/docs/web-security/policies/content-security-policy/directives/frame-ancestors). Cet article est la version pratique « que faire quand je ne peux pas poser le header » ; la référence est la version complète.

## Que faire avec des headers limités ou seulement une balise meta [#que-faire-avec-des-headers-limités-ou-seulement-une-balise-meta]

Adaptez le correctif à ce que votre hébergeur vous laisse réellement contrôler.

**Vous pouvez poser des headers de réponse arbitraires.** Utilisez `frame-ancestors` sur un vrai header `Content-Security-Policy` et laissez tomber `X-Frame-Options` entièrement. `frame-ancestors 'none'` pour bloquer tout framing, `frame-ancestors 'self'` pour la même origine seulement, ou une allowlist nommée pour des partenaires précis. C'est l'option moderne et expressive, à privilégier dès qu'elle est disponible.

```http
Content-Security-Policy: frame-ancestors 'self' https://partner.example
```

**Vous ne pouvez poser qu'une courte liste de headers de sécurité (pas de CSP).** Utilisez `X-Frame-Options: DENY` si rien ne doit framer la page, ou `SAMEORIGIN` si vos propres pages la frament. Acceptez de ne pas pouvoir autoriser un partenaire externe nommé depuis ici. Si un partenaire a réellement besoin de vous embarquer, c'est le cas où il vous faut trouver un moyen de poser un header CSP, il n'existe pas de raccourci limité aux headers pour cela.

**Vous ne pouvez émettre qu'une balise meta.** Vous n'avez aucune protection anti-clickjacking depuis la CSP, car `frame-ancestors` est ignoré dans une balise meta et `X-Frame-Options` ne peut pas être défini depuis le markup du tout (c'est un header de réponse sans équivalent en balise meta). La réponse honnête est que le markup seul ne peut pas défendre contre le framing. Voyez-y une raison de faire configurer ne serait-ce qu'un seul vrai header de sécurité, via la plateforme, un reverse proxy, un edge worker, ou un autre hébergeur, plutôt qu'une chose qu'une balise `<meta>` pourrait masquer.

`X-Frame-Options` est un header hérité, et une fois que vous avez une CSP avec `frame-ancestors`, il est redondant. C'est l'un des headers à retirer à ce moment-là, traité dans [les headers de sécurité hérités à retirer](/fr/blog/legacy-security-headers-to-retire). Ne le gardez que comme repli tant que vous ne pouvez pas poser de CSP.

## Vérifiez ce que vous avez réellement déployé [#vérifiez-ce-que-vous-avez-réellement-déployé]

Parce que l'échec de la balise meta est silencieux, contrôlez la réponse que votre serveur envoie vraiment plutôt que de vous fier au markup. Le [scanner de headers de sécurité](/tools/security-headers) gratuit lit les headers de réponse déployés et montre si `frame-ancestors` (dans la CSP) ou `X-Frame-Options` est présent et quelle valeur il porte, pour que vous confirmiez que la page n'est pas framable quand vous vouliez qu'elle ne le soit pas.

Si la protection anti-clickjacking s'inscrit dans un besoin plus large de surveiller ce que vos pages envoient et chargent dans le temps, la [suite CSP CentralCSP](/platform/csp-builder) surveille votre CSP et les scripts de chaque page à partir du trafic réel, pas seulement d'un scan ponctuel. Vous pouvez [démarrer un essai gratuit](/register) pour voir les rapports et l'état des headers sur tout votre site.

## Sources [#sources]

* [MDN, X-Frame-Options](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options)
* [MDN, CSP frame-ancestors](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors)
* [W3C, Content Security Policy Level 3](https://www.w3.org/TR/CSP3/)
* [OWASP, Clickjacking Defense Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Clickjacking_Defense_Cheat_Sheet.html)

## Articles liés [#articles-liés]

* [Balise meta CSP contre header HTTP](/fr/blog/csp-meta-tags-vs-headers)
* [Headers de sécurité hérités à retirer](/fr/blog/legacy-security-headers-to-retire)
* [Comment construire une CSP solide, étape par étape](/fr/blog/how-to-build-a-strong-csp)
