Tous les articles

Balise meta CSP ou header HTTP

CentralCSP Team ·

Dernière mise à jour:

Vous pouvez déployer une politique de sécurité du contenu (CSP) de deux façons : via un header de réponse HTTP, ou via une balise <meta> dans votre HTML. Elles semblent interchangeables, et pour un simple default-src 'self', elles le sont presque. Mais c'est le header qui fait foi. Il agit plus tôt et prend en charge toutes les parties de la politique, alors qu'une balise meta démarre tard et abandonne silencieusement plusieurs directives. Cet article montre les deux approches, explique les manques, et vous dit quand une balise meta est un repli acceptable.

Les deux façons de déployer une politique

En header, envoyé avec la réponse avant que le moindre HTML soit analysé :

Content-Security-Policy: default-src 'self'; script-src 'self'

En balise meta, qui doit se trouver dans <head> :

<head>
  <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
</head>

Les deux sont standard et largement prises en charge. La différence ne tient pas à savoir si elles fonctionnent, mais à ce que chacune peut faire et au moment où elle entre en jeu.

Header HTTPBalise <meta>
S'applique à partir deAvant l'analyse du premier octet de HTMLUniquement au contenu après l'élément meta
Couvre les ressources préchargées✅ Oui❌ Non
frame-ancestors✅ Appliquée❌ Ignorée
report-uri✅ Appliquée❌ Ignorée
sandbox✅ Appliquée❌ Ignorée
Mode Report-OnlyContent-Security-Policy-Report-Only❌ Pas d'équivalent
Reports de violation✅ Via Reporting-Endpoints❌ Ne peut pas définir de header de réponse
Modifiable après l'analyse❌ Non (ce n'est pas prévu)❌ Non, les éditions de content sont ignorées
Nécessite une config serveur ou CDNOuiNon, ce n'est que du markup

Tout ce qui suit détaille les lignes de ce tableau.

Pourquoi le header est l'option par défaut

Une politique en balise meta démarre tard

Un header est livré avant que le navigateur n'analyse le moindre octet de votre HTML, il régit donc tout le document, y compris les ressources préchargées par le navigateur. Une balise meta n'est que du markup : la politique ne s'applique qu'au contenu que l'analyseur rencontre après l'élément meta. Tout ce qui le précède n'est pas couvert.

C'est une véritable faille de sécurité, pas un détail technique. Si une balise script se trouve au-dessus de votre balise meta, ou si un attaquant injecte du markup plus tôt dans le document, il s'exécute avant même que la politique existe. CSP Level 3 §3.3 précise que les politiques contenues dans les éléments meta ne s'appliquent pas au contenu qui les précède, ce qui explique pourquoi la balise meta doit figurer le plus tôt possible dans <head>. Vous ne pouvez pas non plus modifier une politique meta après coup : éditer l'attribut content en JavaScript après l'analyse est ignoré.

Certaines directives ne fonctionnent qu'en header

Trois directives sont définies pour être ignorées lorsque la politique provient d'une balise meta :

  • frame-ancestors, qui contrôle qui peut intégrer votre page (votre défense contre le clickjacking).
  • report-uri, l'ancienne directive de reporting.
  • sandbox, qui applique des restrictions de sandbox au document.

Placez l'une d'elles dans une balise meta et le navigateur l'abandonne tout en conservant le reste de la politique. Une politique livrée en meta ne peut donc pas du tout protéger contre le framing.

Pas de report-only, pas de reporting

Vous ne pouvez pas non plus exécuter une politique meta en mode test. Le header Content-Security-Policy-Report-Only n'a pas d'équivalent en balise meta, donc la façon sûre de déployer une politique, observer les violations sans rien bloquer, passe uniquement par les headers.

Le reporting ne fonctionne pas vraiment depuis une balise meta non plus. La directive moderne report-to nomme un endpoint que vous définissez avec le header de réponse Reporting-Endpoints, et une balise meta ne peut pas définir de header de réponse, il n'y a donc nulle part où envoyer les reports. Si vous voulez des reports de violation, il vous faut des headers. Consultez Démarrer avec le reporting CSP pour la configuration complète.

Quand une balise meta est acceptable

Parfois, vous ne pouvez réellement pas définir de headers de réponse : un hébergement statique ou un CDN qui ne vous laisse pas les configurer, un CMS où vous ne maîtrisez que le template de page, un prototype rapide. Dans ces cas, une balise meta vaut mieux que pas de politique du tout. Gardez deux choses à l'esprit :

  • Placez la balise meta en premier dans <head>, avant toute autre balise qui charge une ressource, pour que le manque qui la précède soit le plus réduit possible.
  • Acceptez de perdre frame-ancestors, le test en report-only et le reporting. Pour une protection contre le framing sans header CSP, l'ancien header X-Frame-Options reste parfois disponible même quand l'hébergeur limite les headers que vous pouvez définir.

Utiliser les deux : elles s'empilent, elles ne fusionnent pas

Si vous envoyez en même temps une politique en header et une politique en meta, le navigateur ne les combine pas en une seule. Il applique les deux, de façon indépendante, et une ressource doit satisfaire chaque politique pour se charger. Le résultat concret est l'intersection : la règle la plus restrictive l'emporte, et une seconde politique ne peut qu'ajouter des restrictions, jamais les assouplir.

Content-Security-Policy: default-src 'self'
<meta http-equiv="Content-Security-Policy" content="default-src 'self' https://cdn.example">

Ici, la balise meta autorise https://cdn.example, mais pas le header, donc la ressource reste bloquée. La politique meta ne peut pas élargir ce que le header autorise. Deux politiques appliquées se combinent toujours de cette manière, par intersection.

La recommandation

Utilisez un header. Déployez votre politique de sécurité du contenu avec le header de réponse Content-Security-Policy, commencez en report-only pour éliminer les faux positifs, et ajoutez le reporting pour voir ce que la politique bloque. N'utilisez une balise meta que lorsque vous ne pouvez pas définir de headers, en sachant ce à quoi vous renoncez. Le scanner CSP gratuit de CentralCSP vérifie tout ce que vous déployez, header ou meta, et vous dit quelles directives une politique en balise meta abandonne silencieusement ; une fois passé aux headers, CentralCSP collecte les reports de violation que la balise meta n'aurait jamais pu envoyer.

Étapes suivantes

Sources