# Mode enforce ou report-only de la CSP (/fr/blog/csp-enforce-vs-report-only)





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 [#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-Policy`            | `Content-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 quand                   | Vous faites confiance aux règles     | Vous les apprenez encore              |

```http
Content-Security-Policy: default-src 'self'
```

```http
Content-Security-Policy-Report-Only: default-src 'self'; report-to csp-endpoint
```

## Le mode report-only observe sans rien casser [#le-mode-report-only-observe-sans-rien-casser]

Le header [`Content-Security-Policy-Report-Only`](/fr/docs/web-security/policies/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`](/fr/docs/web-security/policies/content-security-policy/directives/report-to), qui nomme un groupe défini dans un header [`Reporting-Endpoints`](/fr/docs/web-security/reporting-api/headers/reporting-endpoints) distinct.

```http
Reporting-Endpoints: csp-endpoint="https://<Endpoint-ID>.report.centralcsp.com"
```

```http
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`](/fr/docs/web-security/policies/content-security-policy/directives/report-uri) que vous envoyez à côté de `report-to`, voir [démarrer avec le reporting CSP](/fr/blog/get-started-csp-reporting).

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](/fr/blog/csp-meta-tags-vs-headers).

## Le mode enforce bloque la violation [#le-mode-enforce-bloque-la-violation]

Basculez les mêmes règles vers le header [`Content-Security-Policy`](/fr/docs/web-security/policies/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.

```http
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](/fr/blog/how-to-build-a-strong-csp).

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 [#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é.

```http
Content-Security-Policy: default-src 'self' https:;
    script-src 'self' https: 'unsafe-inline';
    report-to csp-endpoint
```

```http
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'`](/fr/docs/web-security/policies/content-security-policy/values/csp-keywords) 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](/fr/blog/unsafe-inline-csp) pour le chemin de migration.

## Deux politiques appliquées se combinent, le report-only jamais [#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 [#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 :

```json
{
  "type": "csp-violation",
  "url": "https://example.com/page",
  "body": {
    "documentURL": "https://example.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`](/fr/docs/web-security/policies/content-security-policy/directives/report-to) vers un [endpoint de reporting CentralCSP](/register) et les deux modes arrivent au même endroit.

<img alt="La colonne Disposition, qui sépare les violations appliquées de celles en report-only" src="__img0" width="1365" height="691" />

## Un déploiement simple [#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 [#articles-liés]

* [Plusieurs politiques CSP sur une même page](/fr/blog/multiple-csp-policies)
* [Balise meta CSP ou header HTTP](/fr/blog/csp-meta-tags-vs-headers)

## Sources [#sources]

* [W3C, CSP Level 3 - Content-Security-Policy-Report-Only](https://www.w3.org/TR/CSP3/#cspro-header)
* [W3C, CSP Level 3 - rapports de violation et disposition](https://www.w3.org/TR/CSP3/#create-violation-for-global)
* [MDN, Content-Security-Policy-Report-Only](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy-Report-Only)
* [W3C, Reporting API](https://www.w3.org/TR/reporting-1/)
