Les pubs vous déplaisent ? Aller Sans pub Auj.

Politique de sécurité du contenu Écrire une en-tête de CSP qui fonctionne vraiment

Publié le
Politique de sécurité du contenu : Écrire une en-tête CSP qui fonctionne vraiment 1
ANNONCE · Supprimer ?

La plupart des développeurs savent qu'ils devraient ajouter une politique de sécurité du contenu (CSP) à leurs applications. Peu en ont une qui fonctionne vraiment. Soit elle est trop permissive et annule son objectif, soit elle casse la moitié du site et est supprimée par frustration.

Ce guide explique ce que fait la CSP, quels directives sont importants, et comment écrire une directive qui empêche de véritables attaques sans endommager votre application.

Ce que fait vraiment la CSP

Une politique de sécurité du contenu indique au navigateur d'où il est autorisé à charger des ressources. Des scripts de ce domaine uniquement. Des styles depuis ce CDN. Des images depuis n'importe où. Aucun script en ligne.

Quand un navigateur reçoit une politique de sécurité du contenu (CSP), il applique ces règles avant d'exécuter quoi que ce soit. Si une attaque par injection de scripts (XSS) injecte un script malveillant dans votre HTML, la CSP l'empêche au niveau du navigateur — même si le script a pu passer votre nettoyage des entrées.

C'est la valeur fondamentale : la CSP est votre deuxième ligne de défense lorsque la validation des entrées échoue.

Les directives qui comptent

La CSP dispose de dizaines de directives, mais la plupart des en-têtes de production n'en ont besoin que six :

Directive Ce qu'elle limite Erreur courante
default-src Fonctionnement par défaut pour tout type de ressource non explicitement listé Paramètre 'self', puis oublier que les polices et les cadres ne sont pas couverts
script-src Les URLs de sources JavaScript et l'exécution en ligne Ajouter 'unsafe-inline' pour silencier les erreurs dans la console
style-src Les URLs de sources CSS et les blocs de styles en ligne Oublier votre CDN ou les styles en ligne injectés par des bibliothèques JavaScript
img-src Les sources d'images, y compris les URI de données Manquant data: pour les images en base64, blob: pour les exports de canvas
connect-src Les destinations de XHR, fetch, WebSocket et EventSource Oublier les points de terminaison d'analytiques et les sous-domaines d'API
frame-ancestors Les origines pouvant intégrer votre site dans un <iframe> L'omission complète — laisser le clickjacking ouvert

frame-ancestors remplace l'ancienne X-Frame-Options en-tête et mérite d'être ajoutée même avant d'avoir une couverture complète de la CSP ailleurs.

Pourquoi unsafe-inline Destruction de l'objectif

Quand vous ajoutez 'unsafe-inline' à script-src, vous dites au navigateur : exécutez tout script que vous trouvez, quelle que soit son origine. Cela inclut les scripts injectés par des attaques XSS.

'unsafe-eval' est pire — elle permet eval(), Function()et setTimeout("string"), qui sont des vecteurs d'attaque courants même dans des bases de code apparemment propres.

Une politique incluant l'un de ces documents affiche vos sources sans offrir la moindre protection contre l'injection. L'attaquant n'a pas besoin de savoir d'où vos scripts légitimes sont chargés s'il peut injecter ses propres scripts en ligne.

La méthode correcte : les nonces et les hachages

Si vous avez des scripts en ligne légitimes, vous avez deux options qui ne compromettent pas votre politique :

Les nonces génèrent un token unique par chargement de page. Le serveur l'ajoute à l'en-tête CSP et à l'attribut nonce du script en ligne. Seuls les scripts avec un nonce correspondant sont exécutés.

<!-- CSP header -->
Content-Security-Policy: script-src 'nonce-abc123xyz'

<!-- Inline script with matching nonce -->
<script nonce="abc123xyz">
  window.analyticsId = '...';
</script>

Les hachages calculent un hachage SHA-256 de contenu exact du script. Ajoutez ce hachage à script-src et le navigateur exécute uniquement ce script spécifique — rien d'autre.

Content-Security-Policy: script-src 'sha256-RFWPLDbv2BY+rCkDzsE+0fr8ylGr2R2faWMhq4lfEQc='

Les nonces fonctionnent mieux pour des pages dynamiques où le contenu change à chaque requête. Les hachages conviennent aux scripts statiques qui ne changent pas entre les déploiements.

Déployer avec le mode rapport uniquement en premier

Ajouter la CSP à un site existant sans test est la manière dont on la casse en production. Commencez par l'en-tête de rapport uniquement :

Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self' 'nonce-{random}'; report-uri /csp-violations

Le navigateur applique les règles et enregistre les violations — rien n'est bloqué pour l'instant. Ce journal de violations vous indique exactement ce que vous devez ajouter à la politique avant de la passer en mode de mise en œuvre.

La plupart des déploiements CSP qui cassent des sites ont omis cette étape.

Une vraie CSP pour une application SaaS typique

Voici un en-tête de production prêt à l'emploi pour une application utilisant un CDN, Google Analytics et Stripe. Chaque directive est annotée :

Content-Security-Policy:
  # Tight default: only load from your own origin
  default-src 'self';

  # Scripts: your origin, GA tag manager via nonce, Stripe.js
  script-src 'self' https://www.googletagmanager.com https://js.stripe.com 'nonce-{SERVER_NONCE}';

  # Styles: your origin and Google Fonts CSS
  style-src 'self' https://fonts.googleapis.com;

  # Fonts: your origin and Google Fonts CDN
  font-src 'self' https://fonts.gstatic.com;

  # Images: your origin, CDN subdomain, and base64 data URIs
  img-src 'self' https://cdn.yourdomain.com data:;

  # Fetch/XHR: your API, GA collection endpoint, Stripe API
  connect-src 'self' https://www.google-analytics.com https://api.stripe.com;

  # Stripe renders its fields in an iframe
  frame-src https://js.stripe.com;

  # Nobody should be framing your app
  frame-ancestors 'none';

  # Block <object> and <embed> entirely
  object-src 'none';

  # Force HTTP requests to upgrade to HTTPS
  upgrade-insecure-requests;

Remplacez {SERVER_NONCE} avec une valeur aléatoire cryptographiquement sécurisée générée par requête — par exemple, base64_encode(random_bytes(16)) en PHP ou crypto.randomBytes(16).toString('base64') en Node.

Erreurs CSP courantes

Des étoiles trop larges. script-src * autorise les scripts d'origines quelconques. Vous pourriez dire que vous n'avez pas de politique de scripts du tout.

Oublier les sous-domaines. 'self' ne couvre que votre origine exacte. https://api.yourdomain.com est une origine différente et nécessite une entrée explicite sous connect-src.

Omettre frame-ancestors. La protection contre le clickjacking est indépendante de la protection contre les XSS. Ajoutez-la séparément de l'ensemble des directives.

Configurer la CSP dans plusieurs endroits. Si votre CDN et votre application définissent tous deux un en-tête CSP, le comportement devient imprévisible. Définissez-le dans une seule couche — généralement votre serveur d'origine ou votre reverse proxy.

L'utilisation de report-uri sans un gestionnaire. Les violations génèrent des requêtes POST vers votre point de terminaison à chaque chargement de page affecté. Soit vous les gérez, soit vous les envoyez vers un service comme Report URI.

Construire votre en-tête sans la peine

Suivre chaque domaine que votre page charge via des scripts, des styles, des polices, des images et des appels API devient vite fastidieux. Un générateur en ligne d'en-tête CSP vous permet de configurer chaque directive de manière visuelle et de produire un en-tête prêt à l'emploi que vous pouvez coller directement dans votre configuration serveur.

Utilisez-le comme point de départ, puis vérifiez vos requêtes réelles dans DevTools pour capturer tout ce que le générateur a omis.


Une CSP trop large est une simple décoration. Une CSP trop stricte casse l'expérience utilisateur. Commencez en mode rapport uniquement, affinez progressivement, et utilisez les nonces lorsque des scripts en ligne sont inévitables. Votre politique doit rendre la tâche des attaquants plus difficile — pas la vôtre.

Envie d'une expérience sans pub ? Passez à la version sans pub

Installez nos extensions

Ajoutez des outils IO à votre navigateur préféré pour un accès instantané et une recherche plus rapide

Sur Extension Chrome Sur Extension de bord Sur Extension Firefox Sur Extension de l'opéra

Le Tableau de Bord Est Arrivé !

Tableau de Bord est une façon amusante de suivre vos jeux, toutes les données sont stockées dans votre navigateur. D'autres fonctionnalités arrivent bientôt !

ANNONCE · Supprimer ?
ANNONCE · Supprimer ?
ANNONCE · Supprimer ?

Coin des nouvelles avec points forts techniques

Impliquez-vous

Aidez-nous à continuer à fournir des outils gratuits et précieux

Offre-moi un café
ANNONCE · Supprimer ?