# Plusieurs politiques CSP sur une même page (/fr/blog/multiple-csp-policies)



Vous pouvez envoyer plusieurs politiques de sécurité du contenu (CSP) à une même page, et le navigateur va toutes les respecter en même temps. Une CSP est un header de réponse HTTP qui indique au navigateur quels scripts, styles et autres ressources une page a le droit de charger. Quand une page en porte plusieurs, le navigateur ne les fusionne pas en une seule politique. Il vérifie chacune indépendamment, et une ressource doit passer toutes les politiques pour se charger.

Cette seule règle explique presque tout sur les politiques multiples : ajouter une politique ne peut que rendre une page plus stricte, jamais plus permissive. Un deuxième header ne peut pas réautoriser ce que le premier a bloqué. Cet article montre comment les politiques se combinent, les pièges qui surprennent, et comment tester une politique plus stricte en toute sécurité avant de l'appliquer.

## Comment un navigateur combine plusieurs politiques [#comment-un-navigateur-combine-plusieurs-politiques]

Une page peut récupérer des politiques depuis plusieurs sources en même temps :

* Plusieurs headers de réponse HTTP `Content-Security-Policy`.
* Un seul header `Content-Security-Policy` qui contient plusieurs politiques séparées par des virgules. Chaque segment séparé par une virgule compte comme une politique à part entière.
* Un élément `<meta http-equiv="Content-Security-Policy">`, appliqué en plus des headers.
* Un ou plusieurs headers [`Content-Security-Policy-Report-Only`](/fr/docs/web-security/policies/content-security-policy/report-only), qui signalent les violations mais ne bloquent jamais.

Le navigateur rassemble toutes les politiques actives dans une seule liste et les évalue indépendamment. Pour une requête donnée, il part de l'état « autorisé », puis parcourt la liste. Si une politique appliquée est violée, la requête est bloquée, et rien plus loin dans la liste ne peut la repasser à « autorisé ». C'est le mécanisme derrière la formule que vous entendrez souvent, « la politique la plus restrictive l'emporte ».

Les politiques Report-Only sont ignorées lors de cette décision de blocage. Elles ne sont évaluées que pour produire des reports, donc elles influencent ce que vous voyez dans votre monitoring, pas ce que le navigateur charge réellement.

## Une ressource doit satisfaire chaque politique [#une-ressource-doit-satisfaire-chaque-politique]

Voici l'exemple canonique, deux headers `Content-Security-Policy` sur la même réponse :

```http
Content-Security-Policy: default-src 'self' http://example.com;
                         connect-src 'none';
```

```http
Content-Security-Policy: connect-src http://example.com/;
                         script-src http://example.com/
```

Le deuxième header indique [`connect-src`](/fr/docs/web-security/policies/content-security-policy/directives/connect-src) `http://example.com/`, donc à lui seul il autoriserait cette connexion. Cela n'a aucune importance. La première politique fixe `connect-src 'none'`, et la requête doit passer les deux. Comme une politique interdit toutes les connexions, la connexion est bloquée, et la règle effective pour `connect-src` est `'none'`.

MDN décrit la combinaison de la même manière : ajouter des politiques « ne peut que restreindre davantage les capacités de la ressource protégée ». Il n'y a aucun moyen d'écrire une deuxième politique qui assouplit la première.

L'ordre des headers ne change pas le résultat. Que `connect-src 'none'` arrive en premier ou en second, le résultat est identique, parce que chaque politique est vérifiée indépendamment et que la requête doit toutes les franchir.

## Le piège de l'intersection avec les allowlists d'hôtes [#le-piège-de-lintersection-avec-les-allowlists-dhôtes]

La règle « passer chaque politique » a un effet de bord tranchant quand deux politiques autorisent des ensembles d'hôtes qui se recoupent mais diffèrent. On s'attend à ce que le navigateur prenne l'union des hôtes. Il fait l'inverse.

```http
Content-Security-Policy: script-src 'self' https://trusted.com https://analytics.com
```

```http
Content-Security-Policy: script-src 'self' https://trusted.com
```

Un script depuis `https://analytics.com` passe la première politique mais échoue à la deuxième, donc il est bloqué. Un script depuis `https://trusted.com` passe les deux, donc il se charge. Le résultat effectif est l'intersection des deux allowlists, `'self'` et `https://trusted.com`, parce qu'une ressource doit satisfaire chaque politique individuellement.

C'est facile à provoquer par accident. Si une équipe ajoute une CSP au niveau du CDN ou du proxy et qu'une autre en ajoute une dans l'application, un hôte que seule l'une des deux autorise se retrouve bloqué. Quand une ressource est autorisée par une politique mais pas par l'autre, elle ne se charge pas, point final. Si vous déboguez une ressource qui « devrait » être autorisée, vérifiez si une deuxième politique est en jeu avant de toucher à la directive que vous examiniez.

Le fallback `default-src` est résolu à l'intérieur de chaque politique séparément, avant que la vérification entre politiques ne s'applique. Le navigateur ne construit jamais une politique fusionnée unique, donc le fallback d'une directive dans la politique A n'a aucun effet sur la politique B.

Pour une page qui a besoin d'une politique claire et maintenable, préférez tout consolider dans un seul header bien structuré plutôt que de disperser les directives sur plusieurs. Notre [évaluateur CSP](/tools/csp-evaluator) signale les directives faibles ou contradictoires pour que vous voyiez la vraie politique effective avant de la déployer.

## Tester une politique plus stricte sans casser la page [#tester-une-politique-plus-stricte-sans-casser-la-page]

La raison la plus utile de faire tourner plusieurs politiques, c'est d'appliquer ce qui fonctionne aujourd'hui tout en testant quelque chose de plus serré. Vous appliquez une politique et faites tourner la plus stricte en Report-Only en même temps :

```http
Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.com
```

```http
Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self'
```

Les scripts depuis `https://trusted.com` se chargent toujours, parce que la politique appliquée les autorise. La politique Report-Only est plus stricte, donc le navigateur envoie aussi un report de violation pour chacun de ces scripts, sans rien bloquer. Vous lisez ces reports, confirmez que la politique plus stricte ne casserait pas la page, puis vous la promouvez dans le header appliqué.

Pour collecter les reports, pointez la politique vers un endpoint de reporting. Envoyez un header `Reporting-Endpoints` et référencez-le depuis la directive [`report-to`](/fr/docs/web-security/policies/content-security-policy/directives/report-to) dans chaque politique :

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

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

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

Une chose à anticiper : chaque politique appliquée qu'une requête viole émet son propre report. Si vous faites tourner plusieurs politiques et qu'une seule ressource bloquée en viole deux, vous obtenez deux reports pour ce seul blocage. C'est attendu, puisque le navigateur signale par politique, mais cela signifie que votre volume brut de reports croît avec le nombre de politiques, pas avec le nombre de problèmes distincts. Regrouper les reports par ressource et par directive, plutôt que de compter les événements bruts, limite le bruit. C'est le genre de corrélation que [CentralCSP](/platform/csp-builder) fait pour vous, pour que l'essai en Report-Only se lise comme une courte liste de changements à faire, et non comme un flot d'événements en double.

## Ce qu'il faut retenir [#ce-quil-faut-retenir]

* Plusieurs politiques sont appliquées indépendamment. Une ressource doit toutes les passer pour se charger.
* Une politique supplémentaire ne peut qu'ajouter des restrictions. Elle ne peut jamais réautoriser ce qu'une autre politique a bloqué.
* Les allowlists d'hôtes qui se recoupent s'intersectent. Un hôte autorisé par une seule politique reste bloqué.
* L'ordre des headers n'a pas d'importance.
* Report-Only ne bloque jamais, c'est donc le moyen sûr de tester une politique plus stricte à côté d'une politique qui fonctionne.
* Une seule ressource bloquée peut produire un report par politique violée.

Ce comportement fait partie de CSP Level 3 et fonctionne dans tout navigateur qui prend en charge CSP. Si vous voulez prendre de l'avance, vous pouvez scanner votre configuration actuelle avec le [scanner CSP](/tools/csp-scanner) gratuit et voir comment vos politiques se combinent avant de changer quoi que ce soit.

Pour en savoir plus sur les briques de base derrière ces exemples, voir [comment construire une CSP solide](/fr/blog/how-to-build-a-strong-csp) et [démarrer avec le reporting CSP](/fr/blog/get-started-csp-reporting).

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

* [Mode enforce ou report-only de la CSP](/fr/blog/csp-enforce-vs-report-only)
* [Balise meta CSP ou header HTTP](/fr/blog/csp-meta-tags-vs-headers)
