Comment fonctionne cette vérification
Cette vérification n'agit que si ton site envoie déjà un en-tête Content-Security-Policy ; s'il ne l'envoie pas, c'est le scanner d'en-têtes qui le signale. Scanaris lit la politique complète et cherche les deux mots qui la vident : 'unsafe-inline', qui autorise l'exécution de tout script ou style écrit directement dans le HTML, et 'unsafe-eval', qui autorise la transformation de texte en code avec eval et consorts. Si l'un des deux apparaît, il ouvre un constat de sévérité faible avec la liste des faiblesses trouvées. Faible, parce qu'une CSP imparfaite reste meilleure que pas de CSP, mais la protection contre l'injection de scripts, la raison d'être de la CSP, est presque annulée.
Pourquoi c'est important
Une CSP stricte fait que, même si un attaquant parvient à glisser un <script> dans ta page (via un commentaire non assaini, un paramètre reflété ou une bibliothèque compromise), le navigateur refuse de l'exécuter. Avec 'unsafe-inline' dans script-src, ce script injecté s'exécute quand même : l'en-tête est là, le cadenas semble fermé, mais la porte est ouverte. L'emplacement du mot compte : dans script-src c'est grave ; dans style-src, c'est un risque bien moindre que beaucoup de sites acceptent pour leurs styles en ligne.
Comment corriger
1. Des nonces pour les scripts en ligne
Un nonce est une valeur aléatoire, différente à chaque requête, que tu mets dans l'en-tête et dans chaque balise <script> légitime. Le navigateur n'exécute que les scripts portant cette valeur ; un script injecté ne la connaît pas.
Content-Security-Policy: script-src 'nonce-R4nd0m' 'strict-dynamic'; object-src 'none'; base-uri 'self'
Next.js le fait dans le middleware, en générant le nonce et en le passant à l'en-tête et aux composants ; Nuxt, avec un plugin serveur qui l'injecte dans chaque réponse (c'est ce que fait Scanaris) ; Express, avec un middleware qui le stocke dans res.locals et l'imprime dans les templates.
2. Des hashes pour les scripts fixes
Si un script en ligne ne change jamais, calcule son hash SHA-256 et mets-le dans la politique : 'sha256-…'. Ça marche pour les petits fragments, comme celui d'un gestionnaire de balises, sans monter de nonces.
3. Déplacer le code dans des fichiers
Les gestionnaires onclick="…" et les blocs de script dans le HTML sont la cause habituelle du besoin de 'unsafe-inline'. Passe-les dans des fichiers .js servis depuis ton domaine et le besoin disparaît.
4. Retirer unsafe-eval
C'est généralement exigé par une vieille bibliothèque ou par le mode développement d'un framework qui s'est glissé en production. Vérifie dans la console du navigateur ce qui le demande, puis mets à jour ou remplace cette pièce.
5. Déployer en mode rapport
Publie d'abord la nouvelle politique en Content-Security-Policy-Report-Only avec une directive report-to ou report-uri vers un endpoint à toi. Pendant quelques jours, collecte ce qu'elle bloquerait, ajuste, et quand les rapports sont propres, bascule-la vers l'en-tête bloquant.
Vérifie que c'est corrigé
curl -sI https://tondomaine.com | grep -i "content-security-policy"
Ni 'unsafe-inline' ni 'unsafe-eval' ne doivent apparaître dans script-src. Ensuite, navigue sur ton site avec la console ouverte : tout blocage y apparaît avec la directive qui l'a causé. La théorie complète est dans les en-têtes de sécurité HTTP expliqués pour les humains.
Questions fréquentes
J'utilise Tailwind ou des styles en ligne. Dois-je retirer unsafe-inline de style-src ?
Souhaitable mais pas urgent. Les styles en ligne n'exécutent pas de code. Priorise script-src ; une politique avec 'unsafe-inline' seulement dans style-src protège de l'essentiel.
Google Tag Manager ou un chat de support m'obligent à assouplir la politique.
Presque tous ont une documentation CSP : ils acceptent un nonce ou publient les hashes et domaines dont ils ont besoin. Ajoute leurs origines à script-src et connect-src au lieu de tout ouvrir.
La CSP va-t-elle casser mon site ?
Seulement si tu la passes en mode bloquant sans tester. C'est à ça que sert le mode rapport : il te montre ce qui casserait sans le casser.