Tous les articles

Mode enforce ou report-only de la CSP

CentralCSP Team ·

Dernière mise à jour:

Une politique de sécurité du contenu (CSP) peut soit bloquer ce qui lui déplaît, soit vous le signaler en silence. Ce sont les deux modes : enforce et report-only. Choisissez le mauvais et vous cassez une page qui fonctionnait, ou vous déployez une politique qui ne protège rien. Cet article montre la différence, quand utiliser chacun, comment exécuter les deux en même temps et comment les distinguer dans les rapports que votre navigateur envoie.

La réponse courte

Deux en-têtes de réponse HTTP déterminent le mode dans lequel vous vous trouvez.

  • Content-Security-Policy applique la politique. Le navigateur bloque tout ce qui enfreint une règle (un script inline, une requête vers un hôte que vous n'avez pas autorisé) et envoie un rapport de violation si vous avez configuré le reporting.
  • Content-Security-Policy-Report-Only n'applique rien. Le navigateur laisse tout se charger comme d'habitude et envoie seulement un rapport pour ce qui aurait été bloqué.

Donc enforce protège, report-only observe. Vous commencez presque toujours en report-only pour apprendre comment une politique se comporte face au trafic réel, puis vous basculez les mêmes règles en enforce une fois que les rapports sont propres.

Content-Security-PolicyContent-Security-Policy-Report-Only
Bloque une ressource en infraction✅ Oui❌ Non, elle se charge normalement
Envoie un rapport de violation✅ Oui, si le reporting est configuré✅ Oui, c'est sa seule raison d'être
disposition dans le rapport"enforce""report"
Peut casser une page qui marche✅ Oui, c'est le risque❌ Non
Politiques multiples combinées✅ Oui, par intersection❌ Non, chacune est évaluée seule
Disponible en balise <meta>✅ Oui❌ Non, header uniquement
À utiliser quandVous faites confiance aux règlesVous les apprenez encore
Content-Security-Policy: default-src 'self'
Content-Security-Policy-Report-Only: default-src 'self'; report-to csp-endpoint

Le mode report-only observe sans rien casser

Le header Content-Security-Policy-Report-Only vous aide à surveiller les violations sans appliquer la politique de sécurité. Rien n'est bloqué. Le navigateur évalue chaque requête au regard de la politique, et là où une requête aurait échoué face à une politique appliquée, il enregistre une violation et envoie un rapport à la place.

C'est ce qui fait de ce header la manière sûre de tester. Vous pouvez écrire une politique stricte, la déployer en report-only et observer ce qui casse dans les rapports sans qu'aucun utilisateur ne voie jamais un script bloqué ou une image manquante.

Il y a une condition : le mode report-only n'est utile que si les rapports ont une destination. La manière moderne de mettre cela en place est la directive report-to, qui nomme un groupe défini dans un header Reporting-Endpoints distinct.

Reporting-Endpoints: csp-endpoint="https://<Endpoint-ID>.report.centralcsp.com"
Content-Security-Policy-Report-Only: default-src 'self';
    script-src 'self' https://trusted.example;
    report-to csp-endpoint

Sans endpoint, les violations apparaissent toujours dans la console DevTools du navigateur, mais vous n'avez aucun enregistrement centralisé ni rien sur quoi agir. Pour configurer l'endpoint et le fallback historique report-uri que vous envoyez à côté de report-to, voir démarrer avec le reporting CSP.

Une limite à connaître : le report-only ne peut pas être délivré depuis une balise <meta>. La spec ne prend pas en charge Content-Security-Policy-Report-Only dans un élément <meta> (ni report-uri, frame-ancestors ou sandbox). Une politique délivrée par <meta> est toujours traitée comme appliquée. Le report-only requiert donc un en-tête de réponse HTTP. Plus de détails sur cette distinction dans balises meta CSP ou headers.

Le mode enforce bloque la violation

Basculez les mêmes règles vers le header Content-Security-Policy et le navigateur commence à appliquer. Désormais, une requête qui enfreint une règle est bloquée, et la ressource ne se charge jamais.

Content-Security-Policy: default-src 'self';
    script-src 'self' https://trusted.example;
    report-to csp-endpoint

Vous obtenez toujours des rapports si vous gardez la directive de reporting, mais la différence est réelle : un script inline bloqué ne s'exécute pas, une image interdite n'apparaît pas. C'est le mode que vous voulez une fois que vous faites confiance à la politique, car une politique qui ne bloque pas ne protège pas contre le cross-site scripting (XSS) ni le formjacking.

Dans la console DevTools, le navigateur préfixe les violations report-only par [Report Only] pour que vous sachiez d'un coup d'œil si un message vient d'une politique qui a bloqué ou d'une politique qui s'est contentée d'observer.

Exécutez les deux à la fois pour tester une politique plus stricte

Vous n'avez pas à choisir. Si une réponse porte les deux headers, le navigateur les respecte tous les deux indépendamment. La politique Content-Security-Policy est appliquée, et la politique Content-Security-Policy-Report-Only génère des rapports sans être appliquée.

C'est la manière standard de déployer une politique plus serrée sans risque. Gardez votre politique actuelle qui fonctionne sur le header appliqué pour que le site reste protégé. Placez le candidat plus strict sur le header report-only et observez ses rapports. Quand la politique report-only cesse de générer des violations face au trafic réel, promouvez-la sur le header appliqué.

Content-Security-Policy: default-src 'self' https:;
    script-src 'self' https: 'unsafe-inline';
    report-to csp-endpoint
Content-Security-Policy-Report-Only: default-src 'self';
    script-src 'self' https://trusted.example;
    report-to csp-endpoint

Ici, la page est protégée par une politique appliquée souple pendant que vous mesurez un candidat strict. Le mot-clé 'unsafe-inline' dans la politique appliquée est ce que vous cherchez à supprimer ; la politique report-only l'abandonne et vous indique ce qui casse. Voir pourquoi unsafe-inline annule votre CSP pour le chemin de migration.

Deux politiques appliquées se combinent, le report-only jamais

Une subtilité à bien comprendre : si vous envoyez plus d'une politique appliquée, elles s'empilent par intersection. Une ressource doit satisfaire chaque politique appliquée pour se charger, donc chaque politique supplémentaire ne peut qu'ajouter des restrictions, jamais les assouplir. La règle la plus restrictive l'emporte.

Une politique report-only ne fait pas partie de cette intersection. Elle ne bloque jamais, donc elle ne participe jamais à la décision d'autoriser ou de refuser. Gardez les deux idées séparées : les politiques appliquées se combinent et se resserrent mutuellement ; une politique report-only reste à l'écart et se contente de rapporter.

Les distinguer dans le rapport avec disposition

Chaque rapport de violation CSP porte un champ disposition, et sa valeur est l'une de deux chaînes :

  • "enforce" pour une violation d'une politique Content-Security-Policy appliquée
  • "report" pour une violation d'une politique Content-Security-Policy-Report-Only

Ce seul champ permet à un récepteur de savoir, rapport par rapport, si la politique violée a réellement bloqué la ressource ou s'est contentée de l'observer. Un corps de rapport allégé ressemble à ceci :

{
  "type": "csp-violation",
  "url": "https://api-next.centralcsp.com/page",
  "body": {
    "documentURL": "https://api-next.centralcsp.com/page",
    "effectiveDirective": "script-src",
    "disposition": "report",
    "blockedURL": "https://evil.example/x.js",
    "statusCode": 200
  }
}

La valeur sérialisée est exactement le token "report", pas "reporting". Les deux mêmes chaînes sont exposées sur la propriété DOM SecurityPolicyViolationEvent.disposition si vous traitez les violations en JavaScript au lieu de collecter des rapports.

CentralCSP lit disposition sur chaque rapport qu'il ingère, pour que vous puissiez séparer les événements qui auraient-été-bloqués de ceux réellement bloqués, suivre un déploiement report-only et confirmer qu'une politique applique bien avant de la considérer comme terminée. Pointez votre directive report-to vers un endpoint de reporting CentralCSP et les deux modes arrivent au même endroit.

La colonne Disposition, qui sépare les violations appliquées de celles en report-only

Un déploiement simple

  1. Écrivez votre politique candidate et déployez-la sur Content-Security-Policy-Report-Only avec un endpoint de reporting.
  2. Observez les rapports. Chacun avec une disposition à "report" est quelque chose que la politique aurait bloqué. Corrigez les vrais problèmes et n'assouplissez la politique que là où un rapport est un faux positif.
  3. Quand la politique report-only est silencieuse face au trafic réel, déplacez les mêmes règles vers Content-Security-Policy.
  4. Gardez un candidat plus strict sur le header report-only pour tester votre prochain resserrement, et recommencez.

Les deux headers sont stables et largement pris en charge, donc cette boucle fonctionne partout où tourne un navigateur moderne. Appliquez quand vous faites confiance aux règles, restez en report-only tant que vous les apprenez encore, et lisez disposition pour savoir lequel est lequel.

C'est à l'étape 2 que la boucle cale d'habitude : un site actif produit des milliers de rapports quasi identiques, et le signal se trouve dans les sources distinctes qui reviennent. CentralCSP regroupe les rapports entrants par directive et par origine bloquée en conservant disposition sur chacun, ce qui vous permet de voir le candidat report-only et la politique appliquée côte à côte sur le même site et de savoir si une violation est un vrai blocage ou une répétition.

Articles liés

Sources