Tous les articles

Comment corriger les constats CSP de BitSight

CentralCSP Team ·

Dernière mise à jour:

Un constat BitSight 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é

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

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' 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: 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

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

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

Commencez par la politique que vous voulez obtenir à terme, mais envoyez-la sur le header 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 :

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

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, puis référencez son nom depuis la directive 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 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. L'URL de l'endpoint doit être en HTTPS ; un endpoint non sécurisé est ignoré.

Reporting-Endpoints: csp-endpoint="https://<Endpoint-ID>.report.centralcsp.com"
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, 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

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 :

{
  "type": "csp-violation",
  "url": "https://api-next.centralcsp.com/checkout",
  "body": {
    "documentURL": "https://api-next.centralcsp.com/checkout",
    "blockedURL": "https://cdn.thirdparty.example/widget.js",
    "effectiveDirective": "script-src",
    "disposition": "report",
    "originalPolicy": "default-src 'self'; object-src 'none'; ...",
    "sourceFile": "https://api-next.centralcsp.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

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 contient un nonce, un hash ou 'strict-dynamic', 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 :

<!-- Before: inline handler needs 'unsafe-inline' -->
<button id="buy">Buy</button>
<script>
  document.getElementById('buy').onclick = function () {
    startCheckout();
  };
</script>
<!-- After: external script, no inline handler -->
<button id="buy">Buy</button>
<script src="/js/checkout.js" nonce="r4nd0mN0nce"></script>
// /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' :

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

'strict-dynamic' 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 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, et pour assembler la politique entière de zéro, comment construire une CSP solide.

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.

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

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

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 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 et à améliorer votre note globale de security headers.

Articles liés

Sources