CSP pour un SaaS B2B : questionnaires de sécurité, application connectée et confiance client

Où la CSP compte vraiment pour un SaaS B2B : le questionnaire de sécurité qui la mentionne, les agences de notation qui scorent vos en-têtes et l’application derrière le login où un script compromis ferait le plus de dégâts. Pourquoi les SPA compliquent tout.

Publié le · Mis à jour le

Le site vitrine récolte toute l’attention sur les en-têtes de sécurité, parce que c’est la partie que n’importe qui peut scanner. Puis le questionnaire de due diligence d’un prospect arrive, la question 47 porte sur la Content Security Policy, et la réponse honnête couvre précisément les pages qui comptent le moins.

Pour un SaaS B2B, la CSP intervient à trois endroits. Les questionnaires de sécurité des grands comptes la demandent explicitement. Les équipes sécurité de vos prospects et les agences de notation (BitSight et consorts) scorent vos en-têtes avant toute signature. Et l’application derrière le login est l’endroit où un script compromis ferait de vrais dégâts : jetons de session, données clients, actions d’administration. Traitez l’application elle-même en priorité, déployez la politique en report-only et appuyez-vous sur le reporting côté navigateur, car aucun outil à base de crawler ne passe votre page de connexion.

Vos en-têtes sont lus avant votre contrat

Trois publics différents regardent le même en-tête, et aucun ne vous prévient.

Le questionnaire est le public explicite. Quelque part dans le tableur d’évaluation fournisseur, une ligne parle de protections navigateur ou de mitigation XSS, et « nous n’avons pas de CSP à ce jour » est une case pénible à remplir quand le contrat se chiffre à six zéros.

Le public discret, c’est l’ingénieur sécurité du prospect, qui passe trente secondes à scanner vos domaines avant le call de revue. Nous avons été des deux côtés de ce call. Une politique absente ou truffée d’unsafe-inline ne tue pas un deal à elle seule, mais elle donne le ton de toutes les questions suivantes.

Le troisième public est algorithmique. Les plateformes de notation sécurité scorent les signaux observables de l’extérieur, en-têtes compris, et votre acheteur consulte parfois ce score avant même le premier rendez-vous. Si un rapport BitSight a déjà épinglé votre CSP, le site principal propose un guide pour corriger ces findings.

Une habitude qui rapporte : passer vos propres domaines au scanner CSP avant que le prospect ne le fasse. Celui de CentralCSP est gratuit, sans compte et produit deux scores sur 100, sécurité et qualité, qu’une capture d’écran suffit à glisser dans la réponse au questionnaire, à la place d’un paragraphe de prose.

Pourquoi la SPA complique tout par rapport au site vitrine

Un site vitrine statique se dote d’une CSP en un après-midi : peu de scripts, origines connues, terminé. L’application est une autre affaire, et le coupable est votre bundler.

Une SPA moderne embarque un petit script d’amorçage qui charge ensuite des chunks hachés (main.a3f9c1.js et compagnie), puis en récupère d’autres par import dynamique au fil de la navigation. Les noms de fichiers changent à chaque build. Dès qu’un chunk part d’un CDN ou que le bundler injecte un bout de runtime inline, vous voilà à maintenir des hashes à chaque build, ou à céder à unsafe-inline. Cette dernière option efface en silence l’essentiel de la protection recherchée.

Le motif qui fonctionne : strict-dynamic avec un nonce. Le serveur appose un nonce sur la balise du script d’amorçage. strict-dynamic autorise ensuite ce script de confiance à charger les chunks qu’il crée, sans énumération de votre part. Les extraits inline statiques qui ne bougent jamais peuvent être hachés. Les arbitrages entre les deux méritent leur propre article, nonces ou hashes, mais pour une SPA à chargement de chunks la version courte tient en une phrase : un nonce sur le point d’entrée, et la confiance se propage.

Les crawlers s’arrêtent à votre page de connexion

Le problème structurel de la plupart des outils d’analyse d’en-têtes : ce sont des crawlers. Ils voient ce que voit un visiteur anonyme, c’est-à-dire, pour un SaaS, le site vitrine et un formulaire de connexion. L’application authentifiée, celle qui détient les jetons de session et les données clients, leur échappe entièrement. Scanner la page de login et déclarer l’application couverte, c’est auditer une banque en photographiant le hall d’accueil.

Le reporting côté navigateur inverse la logique. Ajoutez un en-tête Content-Security-Policy-Report-Only sur l’application, et le navigateur de chaque utilisateur réel signale les violations depuis les pages effectivement affichées : le dashboard, la facturation, la console d’administration, chaque combinaison de feature flags. La couverture vient de votre vrai trafic, pas de ce qu’un robot a pu atteindre.

Et non, cela n’expose pas l’écran de vos clients. Un rapport de violation transporte l’URL du document, la directive déclenchée et l’origine ou l’URL du script bloqué. Pas le DOM, pas le contenu des formulaires, rien de ce que l’utilisateur a saisi. Vous apprenez que cdn-douteux.example a tenté de charger un script sur /settings/billing. C’est exactement ce que vous vouliez savoir, et rien d’autre.

Déployer sans casser l’application

La séquence qui marche, condensée :

  • Publiez le report-only sur l’application elle-même, pas seulement sur le site vitrine. Comptez 1 à 4 semaines de trafic représentatif. Les critères de sortie sont détaillés dans combien de temps rester en report-only.
  • Construisez la politique à partir de ce que les sessions authentifiées réelles ont remonté. Le Builder de CentralCSP l’assemble directive par directive et montre chaque source proposée avec la preuve qui la justifie (combien de navigateurs, quelles pages, dernière observation), ce qui compte le jour où il faut expliquer la politique à un auditeur.
  • Activez le Script Inventory. Alimenté par le navigateur, sans agent : chaque script chargé en production, avec origine et hash d’intégrité, sur tous les plans. Sur Scale, la vue Technologies reconnaît la bibliothèque et la version exacte derrière chaque fichier de script et les confronte aux CVE connues. Les dépendances front dérivent d’une façon que votre audit de lockfile ne voit jamais, une bonne partie arrivant par des balises et widgets tiers plutôt que par node_modules.
  • Gardez les scores du scanner à jour et collez-les dans le prochain questionnaire.

Un dernier point, pour le même questionnaire : l’outil qui collecte vos rapports de violation devient un sous-traitant qui manipule vos métadonnées de trafic, et vos clients demanderont où il tourne. CentralCSP traite tout chez OVH en France, rien ne sort de l’UE, avec un DPA public, ce qui garde votre propre réponse RGPD propre. Si le traitement en UE est une exigence dure chez vous, le comparatif des outils de supervision CSP hébergés en UE fait le tour des options.

L’équipe sécurité du prospect regardera de toute façon. Autant qu’elle trouve une vraie politique sur les pages qui comptent.

Questions fréquentes

Les questionnaires de sécurité des grands comptes demandent-ils vraiment une CSP ?

Régulièrement, oui. Le sujet apparaît soit comme une ligne explicite sur la Content Security Policy, soit sous une question plus large sur les protections navigateur. Et même quand le questionnaire n’en parle pas, l’équipe sécurité du prospect scanne vos en-têtes avant de signer, et les plateformes de notation comme BitSight intègrent les en-têtes observables dans le score que votre acheteur consulte. Une CSP absente se voit dans les trois cas.

Comment ajouter une CSP à une single-page application ?

Les listes d’autorisation se battent contre votre bundler, donc préférez un nonce avec strict-dynamic : le serveur appose un nonce sur le script d’amorçage, et strict-dynamic autorise ce script de confiance à charger les chunks hachés et les imports dynamiques sans que vous les énumériez. Déployez d’abord en report-only, observez les violations remontées par les vrais utilisateurs pendant quelques semaines, puis passez en bloquant.

Un scanner CSP peut-il voir la partie connectée de mon application ?

Non. Un scanner fonctionne comme un crawler : il voit vos pages marketing et votre écran de connexion, puis s’arrête. L’application authentifiée, celle qui manipule les jetons de session et les données clients, lui reste invisible. Le reporting côté navigateur inverse la logique : chaque session d’un vrai utilisateur signale les violations depuis les pages réellement affichées, y compris derrière le login.

Les rapports de violation CSP exposent-ils des données clients depuis les pages authentifiées ?

Non. Un rapport de violation contient l’URL du document, la directive déclenchée et l’origine ou l’URL de la ressource bloquée. Il ne contient ni le DOM, ni le contenu des formulaires, ni ce que le client a saisi. Vous apprenez qu’un script inattendu a tenté de se charger sur /billing, pas ce qui figurait sur la page.