# Comment savoir pourquoi votre CSP bloque un script

> Runbook de débogage pour « Refused to load the script because it violates the following Content Security Policy » : lire la directive effective, identifier les causes classiques, corriger par hash ou nonce, puis vérifier à l’échelle avec les rapports de violation.

- Canonical: https://info.centralcsp.com/fr/articles/why-is-csp-blocking-script/
- Published: 2026-08-09
- Language: fr
- Publisher: CentralCSP (https://centralcsp.com)

L’erreur ressemble à ceci :

```text
Refused to load the script 'https://cdn.example.com/widget.js' because it
violates the following Content Security Policy directive: "script-src 'self'".
```

La réponse en un paragraphe : le message nomme la directive effective (ici `script-src`) et la ressource bloquée. Trouvez où cette politique est définie, décidez si le script est légitime, et si oui autorisez-le dans cette directive, de préférence par hash ou nonce plutôt qu’en ouvrant toute une origine. Si votre politique ne contient pas de `script-src`, le navigateur retombe sur `default-src` : c’est donc cette ligne qu’il faut modifier. La suite est le runbook pour faire tout cela sans deviner.

## Étape 1 : lire le message de console pour de vrai

Tout ce dont vous avez besoin tient dans cette ligne, et la plupart des gens la survolent.

La **directive effective** indique quelle liste d’autorisation a échoué. `script-src-elem` désigne une balise script, `script-src` une règle d’exécution, `style-src` une feuille de style que quelqu’un a pris pour un problème de script. Si le message cite `default-src`, votre politique n’a pas de `script-src` du tout et les scripts sont régis par le repli. Cela surprend régulièrement ceux qui ont ajouté `script-src` sur un en-tête et pas sur l’autre.

L’**URL bloquée** dit ce qui a tenté de se charger. `https://cdn.example.com/widget.js`, c’est un chargement externe. Une URL vide ou le mot `inline`, c’est un bloc de script inline. `eval`, c’est une conversion chaîne vers code. `chrome-extension://...`, ce n’était pas votre code.

Pour les scripts inline, Chrome va plus loin et affiche le hash SHA-256 du bloc refusé. Ce hash est un correctif prêt à l’emploi : collé dans la directive, il autorise exactement ce script. Gardez cette idée pour l’étape 2.

Dernière vérification avant de toucher quoi que ce soit : la politique est-elle appliquée ou en report-only ? Un en-tête `Content-Security-Policy-Report-Only` journalise les mêmes violations mais ne bloque rien, et certaines directives s’y comportent différemment ([`upgrade-insecure-requests` y est purement ignorée](/fr/articles/csp-upgrade-insecure-requests-ignored-report-only/)). Si des utilisateurs signalent une casse alors que votre en-tête est en report-only, la CSP n’est pas la coupable.

## Étape 2 : les suspects habituels

Après suffisamment d’astreintes à 2 h du matin, ce sont toujours les cinq mêmes causes qui reviennent.

**Un nouveau script tiers légitime.** Le marketing a ajouté un tag, un fournisseur a changé de CDN, une dépendance npm charge depuis une nouvelle origine. Le correctif paresseux consiste à ajouter l’origine à `script-src`. Le bon correctif est un hash ou un nonce, parce qu’une origine autorise tout ce que cet hôte servira un jour, y compris la version compromise du script. Le choix entre les deux mérite son propre article : [nonces ou hashs](/fr/articles/csp-nonces-vs-hashes/).

**Un script inline sans nonce ni hash.** Dès que la politique contient `script-src` sans `'unsafe-inline'`, chaque bloc inline doit être autorisé explicitement. Avant et après pour un petit extrait inline :

```http
# Avant : le script inline est bloqué
Content-Security-Policy: script-src 'self'
```

```http
# Après : le hash affiché par l'erreur de console, collé dans la directive
Content-Security-Policy: script-src 'self' 'sha256-B2yPHKaXnvFWtRChIbabYmUBFZdVfKKXHbWtWidDVF8='
```

```html
<script>document.getElementById('year').textContent = '2026';</script>
```

Le hash couvre le script octet par octet. Reformatez l’extrait, changez un caractère, et l’empreinte ne correspond plus. La méthode convient donc aux extraits stables. Pour un inline templatisé, prenez un nonce.

**`eval` ou une conversion chaîne vers code.** L’erreur mentionne `'unsafe-eval'` : une bibliothèque appelle `eval()`, `new Function()` ou `setTimeout` avec une chaîne. Ajouter `'unsafe-eval'` fait disparaître l’erreur et rouvre exactement la classe d’injections que la CSP est censée fermer. Notre position : c’est en général une bibliothèque à remplacer, pas une directive à ajouter. Les vieux moteurs de templates et les parseurs d’expressions à l’exécution sont les récidivistes. La plupart ont une version précompilée ou compatible CSP.

**Une extension de navigateur.** Gestionnaires de mots de passe, bloqueurs de pub, extensions de coupons : tous injectent des scripts, et votre politique les bloque. La console montre des sources `chrome-extension://` ou des hashs inline qui ne correspondent à rien de ce que vous avez livré. Ce n’est pas votre bug. N’assouplissez rien pour eux : filtrez-les dans vos rapports et passez à autre chose.

**Deux politiques qui se battent.** Une balise `<meta>` CSP oubliée d’un prototype plus un en-tête posé par le CDN, et les deux s’appliquent : un script doit satisfaire chaque politique présente. Vous pouvez élargir l’en-tête toute la journée, la balise meta continuera de bloquer. Un grep sur `http-equiv="Content-Security-Policy"` dans vos templates s’impose chaque fois qu’un correctif ne produit mystérieusement aucun effet.

## Étape 3 : une console, c’est un seul navigateur

Les DevTools montrent la violation que vous savez reproduire, dans votre navigateur, sur votre machine. L’utilisateur sous Safari 16 derrière un proxy d’entreprise en voit d’autres. Dès que la question devient « quelles pages, quels navigateurs, depuis quand », la console n’est plus le bon outil : votre flux `report-to` devient la source de vérité.

C’est pour cette partie que nous avons construit [le reporting CentralCSP](https://centralcsp.com/fr/platform/monitoring/) : chaque violation indexée par directive, origine, hash et URL de document, si bien que cette question devient un filtre et non une fouille archéologique. Filtrez sur l’origine bloquée et vous obtenez les pages touchées et la date de première apparition en quelques secondes. La mise en place tient dans un en-tête pointant vers l’endpoint managé, environ 2 minutes, avec 90 jours de rétention sur tous les plans, Start à 39,99 €/mois compris.

Et pour la page que vous déboguez à l’instant, l’[extension Chrome](https://centralcsp.com/fr/tools/extension/) gratuite propose un mode Observe qui affiche le flux de violations en direct pendant que vous naviguez, sans compte, entièrement en local. Son mode Rewrite permet ensuite de tester une politique candidate sur le site réel avant de déployer le correctif, ce qui vaut mieux que la boucle déploie-recharge-plisse-les-yeux.

Le runbook, version compressée : lire la directive et l’URL, confronter aux cinq suspects, corriger avec l’autorisation la plus étroite qui fonctionne, puis vérifier dans le flux de rapports que le correctif a bien pris pour tout le monde, pas seulement pour vous.

## Questions fréquentes

### Que signifie « Refused to load the script because it violates the following Content Security Policy » ?

Le navigateur a lu la Content-Security-Policy de la page et constaté qu’un script, externe ou inline, n’est autorisé par aucune source de la directive concernée, en général script-src. Le message de console donne l’URL bloquée et la directive effective. La correction consiste à autoriser ce script dans cette directive, de préférence par hash ou nonce plutôt que par origine entière.

### Pourquoi mon script inline est-il bloqué par la CSP ?

Dès qu’une politique contient script-src sans unsafe-inline, chaque bloc inline doit être autorisé explicitement par un nonce ou un hash. Pour un script inline bloqué, Chrome affiche dans l’erreur le hash SHA-256 calculé : ajoutez cette valeur exacte à script-src et ce script précis, et lui seul, sera autorisé.

### Les extensions de navigateur provoquent-elles des violations CSP ?

En permanence. Les extensions injectent des scripts dans les pages, et la politique de la page les bloque comme n’importe quel code non autorisé. Dans les rapports, elles apparaissent en chrome-extension:, moz-extension: ou sous forme de hashs inline qu’aucun déploiement n’explique. Ce n’est pas votre bug : filtrez-les au lieu d’assouplir la politique.

### Pourquoi mon script reste-t-il bloqué après modification de l’en-tête CSP ?

Cherchez une seconde politique. Une CSP en balise meta et une autre en en-tête s’appliquent toutes les deux, et une ressource doit passer chacune d’elles : la plus stricte gagne. Vérifiez aussi qu’un cache ou un CDN ne sert pas l’ancien en-tête et que la directive modifiée est bien la directive effective : sans script-src, c’est default-src qui gouverne les scripts.
