CSP pour les responsables d’applications web
Concevez et déployez une politique CSP avec des responsabilités, des rapports, des vérifications de compatibilité et un retour arrière explicites.
BotBrowser Team
Vous voulez la documentation structurée pour Déploiement ?
Cet article fait partie de la bibliothèque éditoriale. Pour les étapes de configuration, la référence et les mises à jour continues, passez directement à la section docs.
La Content Security Policy (CSP, politique de sécurité du contenu) est une politique de réponse de l’application qui indique aux navigateurs compatibles quels types de ressources un document peut charger ou exécuter. Elle peut réduire l’impact de certaines erreurs d’injection en limitant scripts, connexions, cadres, Workers et autres ressources. Elle ne constitue pas à elle seule un programme de sécurité complet. L’autorisation côté serveur, l’encodage des sorties, l’examen des dépendances, la conception des sessions, la sécurité du transport et la réponse aux incidents restent des responsabilités distinctes. La spécification CSP Level 3 du W3C définit le modèle et le guide CSP de MDN présente des choix de déploiement.
Considérez la CSP comme une décision produit et déploiement. L’équipe applicative possède les ressources intentionnelles, l’infrastructure contrôle la livraison de la réponse et chaque fournisseur est responsable de son service. Un rapport de violation observe une requête et une politique. Il ne prouve ni une attaque, ni la sécurité de l’application en l’absence de rapports, ni l’achèvement d’une opération métier. Ces limites évitent de transformer un contrôle utile du navigateur en garantie universelle.
Ce guide traite de conception, de responsabilités, du déploiement Report-Only, de tests déterministes, de compatibilité et de retour arrière. Il utilise des pages synthétiques et des reçus limités. Il ne décrit pas comment affaiblir une politique pour charger du contenu non fiable, collecter des identifiants, contourner un contrôle du navigateur ou modifier un service tiers. Pour les autres en-têtes de réponse, consultez le guide des en-têtes HTTP personnalisés et, pour les preuves de version, le guide de validation des navigateurs.
Définir l’objectif et les limites
Commencez par les parcours utilisateurs que la politique doit protéger et les ressources nécessaires. Inventoriez scripts, styles, polices, images, médias, cadres, Workers, WebSockets, destinations de fetch, formulaires et navigation. Incluez les ressources introduites par les gestionnaires de balises, le paiement, l’analytique, l’assistance et les Service Workers. Cet inventaire documente la propriété, il ne s’agit pas d’une copie des journaux du navigateur. Pour chaque élément, indiquez son usage, son responsable, la sensibilité des données, l’environnement et la durée prévue.
Séparez les limites de l’application et celles de l’exécution dans le navigateur. script-src peut limiter une requête de script, mais ne décide pas si un appel API est autorisé et ne donne pas de privilège serveur au script. connect-src limite les connexions du navigateur, sans remplacer les contrôles d’accès du service. Une directive de cadre peut limiter l’intégration du document, mais ne vérifie pas le code ou la politique du document enfant. Inscrivez ces distinctions avant de choisir les valeurs.
Choisissez la politique la plus restreinte qui correspond à un contrat applicatif maîtrisé. Préférez des origines explicites et des chemins stables; évitez les jokers larges lorsque moins de sources suffisent. Vérifiez schémas, ports, redirections et sous-domaines : une expression apparemment interne peut inclure davantage d’hôtes que prévu. Traitez toute origine tierce comme une dépendance avec responsable et révision. N’ajoutez pas une origine uniquement pour faire disparaître une violation si son utilité est inconnue.
Définissez les critères de réussite de chaque parcours. Par exemple : « l’application s’affiche, le module approuvé charge et la ressource synthétique non autorisée est bloquée ». Ce n’est pas : « aucun rapport n’est arrivé, donc l’application est sûre ». Consignez l’état visible attendu, la politique de la réponse finale et les preuves côté application nécessaires à l’achèvement. N’enregistrez pas secrets, contenu client, corps complets ni attributs sans rapport avec le test.
| Question | Preuve à examiner | Responsable et décision |
|---|---|---|
| Quel code exécutable est intentionnel ? | URL finales, code intégré et artefact livré | L’application approuve nonce, empreinte ou source explicite |
| Quelles destinations réseau sont nécessaires ? | Destinations de fetch, WebSocket, Worker et formulaire | Application et service documentent les origines exactes |
| Quels documents intégrés sont fiables ? | URL de cadres, redirections et responsable enfant | Le produit approuve relation et solution de repli |
| Que faut-il signaler ? | Configuration report-to ou report-uri et rétention | Sécurité fixe les limites de confidentialité et d’exploitation |
Choisir les directives sans affaiblir la confiance
La politique exprime un modèle de confiance, non une collection de réparations ponctuelles. default-src fournit une base aux types sans directive dédiée. script-src, style-src, img-src, font-src, connect-src, frame-src, worker-src, media-src, object-src, base-uri, form-action et frame-ancestors correspondent à des décisions différentes. Prise en charge et replis varient selon le navigateur; validez les versions effectivement prises en charge.
Pour le code exécutable, rendez explicite ce qui est autorisé. Un nonce est une valeur propre à la réponse que le serveur associe aux éléments intégrés autorisés et à la politique. Une empreinte lie un bloc connu à son condensat. Les scripts externes exigent aussi une source autorisée et une gestion des dépendances. Ne traitez pas un nonce comme un mot de passe et ne le réutilisez pas entre réponses indépendantes. Il autorise un élément dans une réponse, pas une API, un utilisateur ou un compte fournisseur.
Examinez avec l’équipe les autorisations de scripts et styles intégrés. Une autorisation large facilite parfois le déploiement tout en réduisant la protection. Si un ancien framework l’exige, documentez la dépendance, testez sa migration et limitez l’exception dans le temps et la portée. N’ajoutez pas unsafe-eval, unsafe-inline, un joker ou un domaine fournisseur entier pour faire taire une violation. Toute exception doit avoir une justification, un responsable, une date de révision et un repli observable.
D’autres directives protègent d’autres limites. base-uri empêche une base inattendue de modifier la résolution relative; form-action limite les soumissions; frame-ancestors contrôle les sites qui peuvent intégrer le document, contrairement à frame-src; object-src 'none' convient souvent sans modules historiques. upgrade-insecure-requests influe sur le traitement des URL, sans résoudre toutes les intégrations mixtes. Définissez l’effet attendu avant d’activer une directive.
Ne confondez pas CSP et autres en-têtes. Permissions Policy contrôle la délégation de fonctions; COOP et COEP structurent les relations entre contextes et ressources; les en-têtes de transport couvrent d’autres menaces. CSP complète ces contrôles sans leur fournir leurs garanties. Le guide des contextes sécurisés explique également que l’état de sécurité du navigateur diffère de la politique applicative. Attribuez à chaque contrôle un responsable et un critère d’acceptation.
Déployer avec des observations Report-Only
Commencez par Content-Security-Policy-Report-Only en préproduction ou sur une route de production contrôlée. Un navigateur compatible évalue la candidate et peut transmettre des violations sans bloquer la ressource. Cela révèle des dépendances oubliées, mais ne constitue pas une validation de sécurité. L’absence de rapport peut venir d’un navigateur incompatible, d’un parcours non exécuté, d’un rapport perdu ou d’un autre document. Elle signifie « non observé », pas « sûr ».
Attribuez une version et un responsable à chaque candidate. Conservez son texte, la route ou le modèle qui l’émet, les navigateurs visés, le parcours testé et la date de révision. Réduisez chaque rapport à l’origine du document, la classe d’URI bloquée, la directive effective, le mode, la famille du navigateur et le scénario. Supprimez paramètres, jetons, cookies, contenu de page et autres données sensibles. Le collecteur doit être un service approuvé, avec contrôle d’accès et durée de conservation documentée.
Classez chaque rapport par rapport à l’inventaire. Un URI bloqué peut être un refus prévu, une ressource interne absente, une dépendance tierce, une redirection inattendue ou une valeur générée par le navigateur qui n’est pas une ressource de l’application. Vérifiez requête et réponse finales dans l’environnement approuvé. N’autorisez pas automatiquement l’origine signalée. Identifiez son responsable, les données reçues, sa compatibilité et le résultat visible lorsque la ressource ne charge pas. Le rapport prouve une évaluation du navigateur, pas la fiabilité de l’origine.
Exécutez des cas positifs et négatifs. Le parcours positif charge toutes les ressources promises. Le fixture négatif demande une ressource synthétique que la candidate doit bloquer et vérifie un repli visible et borné. Vérifiez en-tête et comportement pour qu’un test vert ne résulte pas d’une requête jamais effectuée. Utilisez une origine de test contrôlée par l’équipe et ne conservez qu’un résultat bref et l’état du nettoyage.
| Étape | Réponse du navigateur | Preuve conservée | Critère de promotion |
|---|---|---|---|
| Inventaire | Pas encore de candidate | Responsables et parcours | Chaque dépendance nécessaire a un responsable |
| Report-Only | Signale les violations mais charge les ressources | Politique versionnée, rapports minimisés, résultats | Chaque rapport est classé ou accepté comme exception explicite |
| Préproduction appliquée | Peut bloquer les ressources | En-tête final, résultat visible, matrice de compatibilité | Les parcours essentiels réussissent dans les navigateurs pris en charge |
| Production appliquée | Bloque hors contrat | Reçu de déploiement, surveillance et retour arrière | Le responsable accepte le risque de compatibilité restant |
Exécuter un fixture déterministe de ressource bloquée
Le fixture ci-dessous utilise une page de test maîtrisée et une image volontairement bloquée. Il vérifie un repli visible, ne conserve aucune donnée privée et retire le nœud temporaire même si une assertion échoue. Servez la page par le même chemin d’en-têtes que l’application candidate. Déclarez le résultat attendu dans le cas de test, sans le déduire du résultat observé. Le fixture est une observation du navigateur; il ne prouve ni qu’un serveur a rejeté la requête, ni qu’une attaque a été empêchée, ni qu’une opération métier a abouti.
async function checkCspFallback(page, expectedBlocked) {
const result = await page.evaluate(async expected => {
const host = document.createElement('section');
const image = document.createElement('img');
const status = document.createElement('output');
let violation = false;
host.dataset.test = 'owned-csp-blocked-image';
status.setAttribute('aria-live', 'polite');
status.textContent = 'En attente du résultat de la politique';
image.alt = 'Ressource propre au fixture';
const outcome = new Promise(resolve => {
document.addEventListener(
'securitypolicyviolation',
event => {
if (event.blockedURI.endsWith('/fixtures/csp-owned-image.png')) {
violation = true;
resolve('blocked');
}
},
{ once: true }
);
image.addEventListener('load', () => resolve('loaded'), { once: true });
image.addEventListener('error', () => resolve('error'), { once: true });
});
image.src = '/fixtures/csp-owned-image.png';
host.append(image, status);
document.body.append(host);
let timeoutId;
const timeout = new Promise(resolve => {
timeoutId = window.setTimeout(() => resolve('not-observed'), 5000);
});
const observed = await Promise.race([outcome, timeout]);
window.clearTimeout(timeoutId);
const blocked = violation;
status.textContent = blocked
? 'Repli : image bloquée par la politique de l’application'
: observed === 'loaded'
? 'Contrôle : la ressource propre est chargée'
: 'Échec du fixture sans violation de politique';
const passed = expected
? observed !== 'error' && observed !== 'not-observed' && violation
: observed === 'loaded' && !violation;
return { marker: host.dataset.test, observed, blocked, passed };
}, expectedBlocked);
try {
if (!result.passed) throw new Error(`Unexpected CSP fixture result: ${result.observed}`);
return result;
} finally {
await page.evaluate(() => document.querySelector('[data-test="owned-csp-blocked-image"]')?.remove());
}
}
Servez /fixtures/csp-owned-image.png depuis le stub de test maîtrisé, avec une petite réponse d’image valide. La politique de contrôle autorise img-src 'self', donc l’image doit charger; la candidate utilise img-src 'none', et le navigateur émet securitypolicyviolation avant d’afficher le repli. Si l’événement attendu n’apparaît pas, consignez « non observé » et examinez politique, prise en charge et fixture. Ne transformez pas une erreur réseau ou de politique en succès. Un échec déterministe doit laisser le contexte et le répertoire d’artefacts propres.
Exécutez le fixture avec la politique témoin puis la candidate, en passant false puis true. Séparez les reçus. Le résultat « bloqué » n’est utile que si le témoin prouve que le stub maîtrisé est accessible et si la candidate signale une violation de politique. Consignez URL finale, version de politique, version du navigateur, marqueur, résultat et nettoyage. N’enregistrez ni cookies, ni en-têtes d’autorisation, ni journaux complets, ni réponse de production copiée.
Si configuration, assertion et nettoyage peuvent échouer, gardez la première erreur du parcours comme erreur principale. Signalez séparément l’échec de nettoyage et fermez page et contexte dans un finaliseur. Chaque nouvel essai crée un contexte et un reçu. Une réussite ultérieure n’efface pas l’incertitude d’une requête antérieure, surtout en Report-Only où la ressource a pu atteindre un vrai service. Utilisez une origine synthétique maîtrisée pour éviter toute mutation distante.
Valider compatibilité et responsabilités
Testez navigateurs, systèmes, modes document et routes pris en charge. Incluez redirections, cache, Service Workers, scripts modules, Workers, cadres, formulaires et imports dynamiques lorsqu’ils existent. Une configuration présente à la périphérie ne prouve pas que le navigateur a reçu la politique. Examinez la réponse finale après redirections et identifiez le document qui porte la CSP. Un document imbriqué peut posséder sa politique et ses propres décisions de ressources.
Explicitez les contrats. L’application définit ressources nécessaires et repli utilisateur; l’hébergement ou le CDN confirme l’en-tête sur chaque route canonique; la sécurité décide rapports, conservation et limites d’incident; le fournisseur confirme origines, redirections et traitement des données; le responsable de publication arbitre et consigne la version acceptée. Si le service est facultatif, documentez le repli; s’il est essentiel, attendez un contrat compatible avant la promotion.
Examinez les interactions avec cache et modèles. Un nonce par réponse ne se réutilise pas; une page HTML en cache doit porter le nonce correspondant à sa politique. Le collecteur ne doit pas exposer de valeurs sensibles dans les paramètres. Un Service Worker peut servir une ancienne version; testez donc un contexte neuf et un contexte récurrent lorsqu’il est utilisé. L’isolation d’état aide à répéter un parcours, mais ne supprime pas de données serveur et ne répare pas un déploiement périmé.
Examinez les changements comme du code et de l’infrastructure. Comparez directives, sources, génération de nonce ou d’empreinte, route de réponse, destination des rapports et format du reçu. Chaque nouvelle source doit avoir un responsable. Donnez une date de révision aux exceptions. Ne supprimez une source qu’après un parcours positif confirmant qu’elle n’est plus utilisée et un déploiement approuvé. Des rapports calmes sans parcours exécuté ne prouvent pas le retrait d’une dépendance.
| Cas de compatibilité | Vérification | En cas d’échec |
|---|---|---|
| Initialisation intégrée | Nonce ou empreinte correspondant à la réponse | Corriger la génération ou utiliser un module externe maîtrisé |
| Import de module ou Worker | URL finale et directive applicable | Ajouter la source maîtrisée exacte ou utiliser le repli prévu |
| Cadre ou formulaire | Origine enfant, redirections, frame-src, frame-ancestors, form-action | Coordonner avec son responsable; pas de joker global |
| Cache ou réponse Service Worker | Version de politique et de ressource cohérente | Purger par procédure approuvée ou attendre l’expiration contrôlée |
Surveiller, revenir en arrière et maintenir
Activez d’abord l’application pour un ensemble de routes limité. Surveillez les ressources bloquées par version, route, famille de navigateur et dépendance. Agrégez le minimum nécessaire sans conserver le contenu utilisateur. Une hausse peut signaler une nouvelle dépendance, un décalage de cache, une redirection modifiée, un changement de navigateur ou une panne du collecteur. Comparez avec un parcours positif connu avant de changer la politique. Le volume de rapports n’est pas une mesure universelle de sécurité ou disponibilité.
Préparez le retour arrière avant l’application. Conservez politique et version applicative précédentes ainsi que les reçus. Si un parcours essentiel casse, restaurez ensemble la politique connue et le parcours applicatif, puis relancez les fixtures positifs et négatifs. Si le code dépend de la nouvelle ressource, protégez-le par un repli d’exécution ou publiez la version compatible. Le retour arrière ne doit pas retirer sécurité du transport, autorisation ou journaux utiles à l’analyse.
Après un retour, conservez les rapports de la candidate en les identifiant comme historiques. Ne supprimez pas les preuves et ne présentez pas un résultat Report-Only comme une politique appliquée. Ouvrez un suivi limité pour le responsable de la ressource, de la politique ou de la publication. La candidate suivante ne doit modifier qu’une condition connue et rejouer le même fixture afin de distinguer source manquante, nonce invalide, redirection, cache et repli applicatif.
Tenez le registre à jour : en-tête et routes, version, responsables des sources, destination des rapports, conservation, navigateurs, exceptions et date de révision. Revalidez après une mise à jour du framework, un changement CDN, une intégration fournisseur, un nouveau cadre ou Worker, ou le changement d’hôte canonique. La CSP fait partie du contrat déployé; une documentation périmée crée un risque de maintenance.
Ce que BotBrowser peut valider
Les contextes contrôlés de BotBrowser peuvent exécuter un parcours applicatif autorisé avec un état neuf ou déclaré, observer si le navigateur bloque une ressource synthétique et comparer un repli visible lors d’exécutions répétables. La documentation BotBrowser sur l’isolation multi-compte décrit les BrowserContexts isolés et les limites de leur état géré par le navigateur. Cela valide la partie observable du cas CSP : URL finale, métadonnées de politique auxquelles le test est autorisé à accéder, résultat de chargement ou blocage et reçu de nettoyage.
BotBrowser ne rédige ni ne déploie les en-têtes, ne choisit pas une liste de sources sûre pour l’application, ne valide pas l’autorisation serveur ou la chaîne d’approvisionnement et ne prouve pas l’absence de vulnérabilité d’injection. Il ne rend pas fiable une ressource tierce, n’accorde pas d’exception à un fournisseur et ne garantit pas le même support des directives dans tous les navigateurs. Il ne prouve pas davantage la création d’un dossier, l’acceptation d’un paiement, la révocation d’une session ou l’absence d’incident. Ces faits nécessitent des preuves de l’application, du service, de l’infrastructure et de la sécurité.
Limitez les reçus BotBrowser : scénario, version de politique, URL finale, build navigateur, résultat visible, classification de la route synthétique et nettoyage. N’y placez pas contenu client, identifiants, cookies ou charges complètes. Étiquetez le résultat « observation de la politique du navigateur » et reliez séparément toute preuve métier nécessaire. Un contexte propre est une condition d’exécution, pas une suppression de données serveur ni une certification de sécurité.
Avant publication, les responsables confirment quatre limites : un rapport ne prouve pas une attaque; l’absence de rapport ne prouve pas la sécurité; une ressource bloquée ne prouve ni rejet ni suppression côté serveur; une observation BotBrowser ne remplace pas autorisation applicative ou revue des dépendances. Consignez politique retenue, compatibilité, repli, responsable du suivi et artefact de retour arrière. La protection progresse ainsi sans être affaiblie pour charger une dépendance inconnue.
Rejouez les mêmes parcours lorsque la politique ou une dépendance maîtrisée évolue. Une comparaison limitée et versionnée aide à distinguer un changement de décision du navigateur, de repli applicatif ou de résultat d’un service distinct.
BotBrowser Team
Sources
Articles Connexes
Faites passer BotBrowser de la recherche à la production
Utilisez ces guides pour comprendre le modèle, puis passez à la validation multi-plateforme, aux contextes isolés et au déploiement navigateur prêt pour l'échelle.