# Comment corriger les constats CSP de BitSight (/fr/blog/fix-bitsight-csp-findings)



Un constat [BitSight](https://www.bitsight.com/) au sujet de votre politique de sécurité du contenu (CSP) est corrigeable, et vous pouvez le faire sans casser le site. La voie fiable est de déployer une politique stricte d'abord en report-only, d'observer ce que fait le trafic réel, de resserrer la politique à partir de ces preuves, puis de la passer en application. Cet article parcourt chaque phase, pourquoi elle fonctionne, et comment relier chaque conseil de remédiation de BitSight à un changement concret dans votre header.

CentralCSP publie aussi une démarche outillée pour la même correction, qui s'appuie sur le scanner et le builder pour faire le travail. Cet article est le compagnon de celui-là et va plus loin sur les mécanismes : ce que contient réellement un rapport de violation, comment le lire, et comment convertir une politique non sûre en politique stricte.

## Ce que BitSight signale et pourquoi cela a changé [#ce-que-bitsight-signale-et-pourquoi-cela-a-changé]

BitSight a re-noté la sécurité applicative en 2025. Le vecteur de risque Web Application Security (WAS) a remplacé l'ancien vecteur Web Application Headers dans la note principale, entré en production en juillet 2025 après un aperçu ouvert le 8 avril 2025, et il porte le même poids de 5 %. WAS exécute 21 évaluations réparties sur 5 catégories, dont l'une est nommée "Content Security Policy (CSP) Violations".

Le scan est non intrusif. BitSight charge votre domaine dans un navigateur headless, capture la réponse complète de la page, et inspecte des mesures de sécurité comme Subresource Integrity (SRI) et la CSP pour vérifier qu'aucune ressource distante non fiable n'est chargée. Il n'envoie pas de requêtes forgées pour déclencher ou exploiter une vulnérabilité ; il lit ce que la page et ses headers font réellement.

Quelques conséquences en découlent :

* BitSight lit vos headers de réponse comme le ferait un navigateur. Les noteurs évaluent le header appliqué sur votre site en direct, alors déployez un header `Content-Security-Policy` appliqué, pas seulement du report-only, pour faire bouger la note. Le report-only est l'outil pour construire la politique en toute sécurité ; le header appliqué est ce qui efface le constat.
* Les constats sont une heuristique de notation sur la chaîne du header, pas un test de validité de la CSP. Une politique peut être valide au regard de la spec et tout de même signalée, et un pattern signalé est quelque chose à retirer parce qu'il affaiblit la politique, pas parce qu'il est invalide.

### Ce que couvrent généralement les constats CSP [#ce-que-couvrent-généralement-les-constats-csp]

Les constats liés à la CSP chez BitSight tombent en général dans quatre catégories :

* Une politique de sécurité du contenu manquante sur l'hôte évalué.
* Une configuration faible qui utilise des mots-clés non sûrs comme [`'unsafe-inline'`](/fr/docs/web-security/policies/content-security-policy/values/csp-keywords) ou `'unsafe-eval'`.
* Des violations CSP, où des ressources légitimes sont bloquées par la politique.
* Une politique trop permissive qui utilise un joker ou autorise des schémas non sûrs.

Les conseils de remédiation que fait remonter BitSight s'alignent sur les bonnes pratiques de CSP stricte. Paraphrasés, ils reviennent à : retirer `'unsafe-eval'`, retirer `'unsafe-inline'`, retirer [`blob:`](/fr/docs/web-security/policies/content-security-policy/values/csp-scheme-source) et `data:` des listes de sources, et retirer tout astérisque isolé (`*`).

### Pourquoi corriger la CSP peut ne pas faire bouger votre note tout de suite [#pourquoi-corriger-la-csp-peut-ne-pas-faire-bouger-votre-note-tout-de-suite]

Chaque constat reçoit une note textuelle par gravité, dont BAD, WARN et FAIR font partie, et ces notes se cumulent en une note de A à F. Les constats les plus graves pèsent le plus, donc un constat de gravité supérieure ailleurs dans WAS peut retenir votre note tant qu'il n'est pas résolu.

Ainsi, si votre constat CSP est noté FAIR alors qu'un constat WARN ou BAD se trouve au-dessus, corriger la seule politique peut ne pas relever la note tant que les constats de gravité supérieure ne sont pas résolus. Corrigez la CSP parce qu'elle durcit réellement la page, et attendez-vous à ce que le score ne bouge qu'une fois les éléments les plus graves résolus.

## Le workflow de correction [#le-workflow-de-correction]

La remédiation comporte cinq phases : déployer strict en report-only, ajouter un endpoint de reporting, collecter les rapports de violation, resserrer, puis appliquer.

```
report-only  ->  collect reports  ->  tighten  ->  enforce
```

### 1. Déployez une politique stricte en report-only [#1-déployez-une-politique-stricte-en-report-only]

Commencez par la politique que vous voulez obtenir à terme, mais envoyez-la sur le header [`Content-Security-Policy-Report-Only`](/fr/docs/web-security/policies/content-security-policy/report-only). Le navigateur analyse la politique et signale ce qu'il bloquerait, mais ne bloque rien, vous pouvez donc déployer une politique stricte sur du trafic réel sans risquer une page cassée. Report-only est un header de réponse HTTP uniquement ; il n'est pas disponible via un élément `<meta>`.

Un point de départ strict ressemble à ceci :

```http
Content-Security-Policy-Report-Only:
    default-src 'self';
    script-src 'self';
    style-src 'self';
    img-src 'self';
    font-src 'self';
    connect-src 'self';
    object-src 'none';
    base-uri 'none';
    form-action 'self';
    frame-ancestors 'none';
    report-to csp-endpoint
```

### 2. Pointez les rapports vers un endpoint [#2-pointez-les-rapports-vers-un-endpoint]

Les rapports n'aident que s'ils sont livrés quelque part. Déclarez un endpoint de reporting avec le header de réponse [`Reporting-Endpoints`](/fr/docs/web-security/reporting-api/headers/reporting-endpoints), puis référencez son nom depuis la directive [`report-to`](/fr/docs/web-security/policies/content-security-policy/directives/report-to) dans la politique ci-dessus. `Reporting-Endpoints` est le standard actuel et est largement disponible. L'ancien header `Report-To` est déprécié, et la directive [`report-uri`](/fr/docs/web-security/policies/content-security-policy/directives/report-uri) est dépréciée mais encore honorée, il vaut donc la peine de l'inclure en repli. Envoyez à la fois `report-to` et `report-uri` pour la plus large couverture, comme détaillé dans [report-uri vs report-to](/fr/blog/report-uri-vs-report-to). L'URL de l'endpoint doit être en HTTPS ; un endpoint non sécurisé est ignoré.

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

```http
Content-Security-Policy-Report-Only:
    default-src 'self';
    object-src 'none';
    base-uri 'none';
    report-to csp-endpoint;
    report-uri https://<Endpoint-ID>.report.centralcsp.com
```

Vous pouvez mettre en place un endpoint de reporting et un tableau de bord pour les rapports avec [CentralCSP](/register), qui ingère les rapports de violation CSP et les transforme en un inventaire de scripts et une vue par directive plutôt qu'en JSON brut.

### 3. Lisez les rapports de violation [#3-lisez-les-rapports-de-violation]

Les rapports de violation CSP modernes arrivent via la Reporting API sous forme de tableau JSON, envoyé en POST avec le type de contenu `application/reports+json`. L'ancien chemin `report-uri` envoie un seul objet de type `application/csp-report`. Les champs qui vous importent pour décider quoi autoriser sont listés en entier dans [la référence des champs du rapport de violation CSP](/fr/blog/csp-violation-report-fields) :

```json
{
  "type": "csp-violation",
  "url": "https://example.com/checkout",
  "body": {
    "documentURL": "https://example.com/checkout",
    "blockedURL": "https://cdn.thirdparty.example/widget.js",
    "effectiveDirective": "script-src",
    "disposition": "report",
    "originalPolicy": "default-src 'self'; object-src 'none'; ...",
    "sourceFile": "https://example.com/checkout",
    "sample": "",
    "lineNumber": 42,
    "columnNumber": 9
  }
}
```

Lisez `effectiveDirective` pour voir quelle directive a bloqué la ressource, et `blockedURL` pour voir ce qui a été bloqué. `disposition` vaut `report` tant que vous êtes en report-only et devient `enforce` une fois que vous changez de header, ce qui est un moyen rapide de confirmer quel header a produit un rapport donné. Pour les violations de script et de style inline, `sample` ainsi que les numéros de ligne et de colonne vous pointent vers le code exact à corriger.

Parcourez les rapports et triez chaque ressource bloquée dans l'une de deux piles : légitime (quelque chose dont la page a vraiment besoin) ou indésirable (une ressource injectée ou obsolète que vous ne voulez pas). Vous autorisez la première pile et laissez la seconde bloquée. Collectez assez longtemps pour capturer l'usage réel sur votre trafic avant de faire confiance à la liste.

### 4. Resserrez la politique [#4-resserrez-la-politique]

C'est ici que vous retirez les patterns signalés par BitSight, à l'aide des preuves issues des rapports. Reliez chaque conseil à une modification concrète.

**Retirez `'unsafe-inline'` des scripts.** Les scripts et styles inline sont un vecteur XSS de premier plan, ce qui explique pourquoi le mot-clé est signalé. La correction consiste à donner à chaque script inline légitime un nonce ou un hash. Quand [`script-src`](/fr/docs/web-security/policies/content-security-policy/directives/script-src) contient un [nonce, un hash](/fr/docs/web-security/policies/content-security-policy/values/csp-hashes-nonce) ou [`'strict-dynamic'`](/fr/blog/strict-dynamic-csp), le navigateur ignore entièrement `'unsafe-inline'`, donc le laisser ne fait rien pour les navigateurs modernes et n'affaiblit la politique que pour les plus anciens. Cette suppression est le mécanisme qui vous permet de retirer le mot-clé en toute sécurité.

Externalisez les event handlers inline quand vous le pouvez :

```html
<!-- Before: inline handler needs 'unsafe-inline' -->
<button id="buy">Buy</button>
<script>
  document.getElementById('buy').onclick = function () {
    startCheckout();
  };
</script>
```

```html
<!-- After: external script, no inline handler -->
<button id="buy">Buy</button>
<script src="/js/checkout.js" nonce="r4nd0mN0nce"></script>
```

```javascript
// /js/checkout.js
document.getElementById('buy').addEventListener('click', function () {
  startCheckout();
});
```

Pour les scripts inline que vous ne pouvez pas externaliser, attachez un nonce. Le nonce doit avoir au moins 128 bits d'entropie, être en base64, généré par un générateur de nombres aléatoires cryptographiquement sûr, et frais et unique à chaque réponse. Ne réutilisez jamais un nonce d'une requête à l'autre.

**Adoptez la politique stricte canonique.** La forme cible recommandée pour une CSP stricte est basée sur un nonce ou un hash, avec `'strict-dynamic'` :

```http
Content-Security-Policy:
    script-src 'nonce-{RANDOM}' 'strict-dynamic';
    object-src 'none';
    base-uri 'none'
```

```http
Content-Security-Policy:
    script-src 'sha256-{HASH}' 'strict-dynamic';
    object-src 'none';
    base-uri 'none'
```

[`'strict-dynamic'`](/fr/docs/web-security/policies/content-security-policy/values/csp-keywords) indique au navigateur de faire confiance aux scripts chargés par un script déjà de confiance (avec nonce ou hash), et d'ignorer les listes d'hôtes autorisés, `'self'` et les sources de schéma pour `script-src`. Si votre politique actuelle repose sur une longue liste d'hôtes de scripts autorisés, comprenez que `'strict-dynamic'` rend cette liste sans effet pour les scripts, ce qui est généralement ce que vous voulez.

**Retirez les jokers et les schémas non sûrs.** Un `*` isolé et une source de schéma `http:` réduisent à néant l'intérêt de la politique. Remplacez `*` par les hôtes spécifiques que les rapports vous montrent réellement chargés. Remplacez les sources `data:` et `blob:` par des hashes ou des origines spécifiques ; un attaquant capable d'injecter une URL `data:` dans une directive qui l'autorise peut souvent contourner la politique. Ne gardez une [source de schéma](/fr/docs/web-security/policies/content-security-policy/values/csp-scheme-source) que là où un rapport prouve qu'une ressource légitime en a besoin et qu'aucune alternative plus stricte n'existe.

**Retirez `'unsafe-eval'`.** Ce mot-clé réactive l'exécution de chaîne en code (`eval`, `new Function` et similaires) sur toute la page. Si une bibliothèque en a besoin, préférez un build qui évite `eval` ou déplacez ce code hors de la page plutôt que de rouvrir la politique.

Pour en savoir plus sur les raisons de retirer le mot-clé inline et comment le faire proprement, voyez [le procès de unsafe-inline](/fr/blog/unsafe-inline-csp), et pour assembler la politique entière de zéro, [comment construire une CSP solide](/fr/blog/how-to-build-a-strong-csp).

### 5. Appliquez [#5-appliquez]

Quand le flux report-only est silencieux, c'est-à-dire quand les seuls rapports restants concernent des ressources que vous avez délibérément choisi de ne pas autoriser, déplacez la même politique validée de `Content-Security-Policy-Report-Only` vers le header d'application `Content-Security-Policy`.

```http
Content-Security-Policy:
    script-src 'nonce-{RANDOM}' 'strict-dynamic';
    style-src 'self';
    img-src 'self';
    connect-src 'self';
    object-src 'none';
    base-uri 'none';
    form-action 'self';
    frame-ancestors 'none';
    report-to csp-endpoint;
    report-uri https://<Endpoint-ID>.report.centralcsp.com
```

Gardez le reporting actif après avoir appliqué. Le champ `disposition` indique désormais `enforce`, donc tout nouveau rapport signifie un vrai blocage en production, ce qui est votre alerte précoce qu'un changement a cassé quelque chose ou que quelqu'un sonde la page.

Une mise en garde : une page peut passer fonctionnellement en report-only et tout de même casser en application, parce que le report-only ne bloque jamais rien. Ne sautez pas l'étape qui consiste à atteindre zéro violation légitime avant de basculer le header.

## Une note sur les hôtes multiples [#une-note-sur-les-hôtes-multiples]

Les scanners évaluent par hôte. Si votre parc s'étend sur plusieurs sous-domaines ou origines, chaque hôte a besoin de sa propre politique appliquée et de sa propre liaison d'endpoint de reporting. Un header sur `www` ne fait rien pour `app` ou `checkout`.

## Où cela vous mène [#où-cela-vous-mène]

Corriger un constat CSP de BitSight est une séquence, pas un seul interrupteur : déployez strict en report-only, collectez de vrais rapports de violation, resserrez à partir de ces preuves en remplaçant les mots-clés non sûrs et les jokers par des nonces ou des hashes, puis appliquez. Le même header appliqué qui efface le constat est aussi une protection réellement meilleure contre le XSS et l'injection de ressources.

Si le JSON de rapport brut est plus que ce que vous voulez trier à la main, [ouvrez un compte CentralCSP gratuit](/register) pour collecter les rapports, les voir regroupés par directive et par ressource, et suivre la politique dans le temps à mesure que vous la resserrez.

Le même header appliqué aide aussi à [corriger les mêmes constats sur SecurityScorecard](/fr/blog/fix-securityscorecard-csp-findings) et à [améliorer votre note globale de security headers](/fr/blog/improve-security-headers-grade).

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

* [BitSight RAU25 et pourquoi la CSP est désormais notée](/fr/blog/bitsight-rau25-was-csp)
* [Démarrer avec le reporting CSP](/fr/blog/get-started-csp-reporting)

## Sources [#sources]

* [W3C, Content Security Policy Level 3](https://www.w3.org/TR/CSP3/)
* [OWASP, HTTP headers cheat sheet](https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html)
* [MDN, Content-Security-Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy)
