Content Security Policy : sécuriser un front moderne sans casser l’analytics
Mettez en place une Content Security Policy progressive pour réduire les XSS sans bloquer scripts tiers, analytics et déploiements.
Déployez la CSP progressivement : observez d’abord les violations en production, n’autorisez que les ressources justifiées, puis activez le blocage. Cette méthode réduit l’impact de nombreuses XSS sans couper brutalement l’analytics, le consentement ou le paiement.
La CSP indique au navigateur quelles sources de scripts, styles, images, connexions ou cadres sont autorisées. Une injection XSS qui tente d’exécuter un script inline ou de charger un fichier depuis une source non approuvée peut alors être bloquée.
Elle ne remplace ni l’échappement des données, ni la validation des entrées, ni la revue de code. C’est une défense supplémentaire : une erreur de rendu ou une dépendance vulnérable a moins de chances de devenir une exécution JavaScript exploitable.
Établir une politique fondée sur les usages réels
Commencez avec default-src 'self', puis ouvrez explicitement les ressources nécessaires. La directive centrale est généralement script-src : évitez 'unsafe-inline', qui réautorise une large part des scripts inline injectés et réduit fortement l’intérêt de la politique. Le guide de l’OWASP sur la CSP détaille ces limites.
Inventoriez les ressources chargées sur les parcours importants : accueil, authentification, paiement, espace connecté et formulaires. La préproduction ne reproduit pas toujours les bannières de consentement, tags marketing ou outils activés seulement en production.
- Scripts : bundles internes, gestionnaire de tags, consentement, chat, captcha et paiement.
- Connexions : API, WebSocket, mesure, collecte d’erreurs et services tiers.
- Styles et médias : feuilles externes, polices, images, lecteurs vidéo et iframes.
- Fonctionnalités navigateur : workers, manifests, frames embarquées et envoi de formulaires.
Utilisez les DevTools pour repérer les domaines chargés, puis les rapports CSP pour vérifier les usages réels. Un même service peut relever de plusieurs directives : pour Google Analytics, le script concerne par exemple script-src, tandis que les requêtes de collecte concernent connect-src.
N’ajoutez pas de domaine « au cas où ». Une règle comme https: pour les scripts ou des jokers trop larges affaiblit la CSP ; chaque origine doit correspondre à une dépendance, un propriétaire et un besoin documenté.
Passer du mode Report-Only au blocage
Envoyez d’abord l’en-tête HTTP Content-Security-Policy-Report-Only. Le navigateur évalue la politique et émet des rapports de violation, sans bloquer les ressources concernées.
Configurez un endpoint de collecte adapté à votre infrastructure et examinez les rapports par page, navigateur et directive. Les mécanismes modernes de reporting s’appuient notamment sur Reporting-Endpoints et report-to ; vérifiez la compatibilité de la collecte avec les navigateurs visés. La documentation MDN sur Content-Security-Policy-Report-Only précise le comportement de ce mode.
Qualifiez les violations avant de créer des exceptions. Une extension navigateur, un antivirus ou une tentative d’attaque peut produire un rapport sans révéler une dépendance légitime.
- Corrigez les chargements internes non prévus.
- Ajoutez les origines tierces validées, directive par directive.
- Testez les parcours conditionnels : consentement refusé, connexion, erreur, paiement et navigation mobile.
- Passez à Content-Security-Policy lorsque les violations utiles sont comprises.
Conservez le reporting après l’activation. Un nouveau tag ou une mise à jour de prestataire peut sinon provoquer une panne silencieuse pour une partie des visiteurs.
Autoriser les scripts contrôlés sans ouvrir les scripts inline
Utilisez un nonce pour un script inline nécessaire et rendu par votre application. Générez cette valeur aléatoire côté serveur pour chaque réponse, puis ajoutez-la à l’en-tête CSP et à la balise autorisée ; vous évitez ainsi de recourir à 'unsafe-inline'.
Un nonce suppose que le serveur ou le rendu SSR puisse générer une valeur par réponse. Un fichier HTML entièrement statique ne peut pas fournir un nonce renouvelé sans mécanisme complémentaire.
Préférez un hash pour un bloc inline dont le contenu exact est stable. Toute modification du script, y compris une variable ou un identifiant de déploiement, impose de recalculer le hash.
Employez strict-dynamic lorsqu’un script de confiance, identifié par un nonce ou un hash, charge lui-même d’autres scripts. Dans les navigateurs qui le prennent en charge, la confiance se propage à ces scripts ; gardez toutefois des sources hôtes explicites pour les navigateurs plus anciens et vérifiez le comportement des tiers.