Imposer SRI sur chaque script avec Integrity-Policy
CentralCSP Team ·
Dernière mise à jour:
Subresource Integrity (SRI) protège un élément à la fois. Vous hashez un fichier, collez le digest dans l'attribut integrity de la balise, et le navigateur le vérifie. Le prochain script que quelqu'un ajoute sans hash n'est pas protégé, et rien ne vous le signale. Le header de réponse Integrity-Policy corrige ce problème de portée : il exige SRI sur chaque script avec un seul header, et signale ceux qui en manquent.
La version courte : envoyez Integrity-Policy: blocked-destinations=(script) et le navigateur bloque tout script qui se charge sans métadonnées d'intégrité valides. Ajoutez une directive endpoints=() plus un header Reporting-Endpoints et il signale chaque script bloqué sous forme de report integrity-violation. Une variante report-only vous laisse mesurer l'écart avant d'imposer. Cet article couvre la syntaxe, le câblage du reporting, et comment il transforme SRI d'un opt-in par balise en une règle à l'échelle du site.
Disponibilité récente
L'application d'Integrity-Policy pour la destination script est devenue récemment disponible dans les versions actuelles de Chrome, Firefox et Safari, et Firefox a gagné la livraison vers un endpoint. C'est encore récent et pas encore Baseline, donc confirmez la couverture pour les navigateurs qui vous importent et traitez-le comme une couche d'application plus un signal de reporting.
Ce que fait Integrity-Policy
SRI est un opt-in par élément. Rien n'empêche un développeur d'ajouter un nouveau <script src> sans attribut integrity, et cette seule balise sans hash est l'écart dont un attaquant a besoin. Integrity-Policy le ferme en énonçant l'exigence une fois, au niveau du header de réponse, au lieu de sur chaque balise.
Vous nommez les destinations de ressources qui doivent être protégées par intégrité, et le navigateur exige alors une valeur integrity valide à chaque chargement de ce type. Un script sans elle est bloqué (ou, en mode report-only, signalé). La référence complète est la page de la politique Integrity-Policy.
Comment le configurer
Le header minimal nomme la destination à protéger :
Integrity-Policy: blocked-destinations=(script)blocked-destinations est la directive requise. Aujourd'hui, la valeur pratique est script ; la destination style a un support plus étroit. Avec ce header seul, tout script qui se charge sans attribut integrity correct est bloqué, sans report.
Pour obtenir des reports, ajoutez une directive endpoints=() et déclarez ce nom d'endpoint dans un header Reporting-Endpoints. Les deux headers vont dans des blocs séparés :
Reporting-Endpoints: integrity-endpoint="https://<Endpoint-ID>.report.centralcsp.com"Integrity-Policy: blocked-destinations=(script), endpoints=(integrity-endpoint)Un détail de câblage fait trébucher les gens : Integrity-Policy sélectionne son endpoint de reporting avec la directive endpoints=(), pas le paramètre report-to= qu'utilisent COOP, COEP et Permissions-Policy. Le nom à l'intérieur de endpoints=() doit correspondre à un nom déclaré dans Reporting-Endpoints.
Commencez en mode report-only
Activer le blocage avant de savoir quels scripts portent SRI cassera la page : chaque script légitime mais sans hash se fait bloquer avec les mauvais. Utilisez d'abord la variante report-only. Elle signale chaque script qui manque d'intégrité valide sans rien bloquer, pour que vous voyiez la liste complète avant d'imposer.
Integrity-Policy-Report-Only: blocked-destinations=(script), endpoints=(integrity-endpoint)Laissez-la tourner jusqu'à ce que les reports cessent de faire remonter des scripts que vous n'avez pas encore hashés. Ajoutez ensuite l'attribut integrity (ou supprimez la dépendance) pour tout ce qui est sur la liste, et basculez le header en Integrity-Policy pour imposer.
À quoi ressemble un report de violation
Quand un script se charge sans intégrité valide, le navigateur émet un report integrity-violation vers votre endpoint. Il nomme la page, le script bloqué, et si la politique imposait ou ne faisait que signaler.
{
"type": "integrity-violation",
"age": 5,
"url": "https://api-next.centralcsp.com/",
"user_agent": "Mozilla/5.0 ...",
"body": {
"documentURL": "https://api-next.centralcsp.com/",
"blockedURL": "https://api-next.centralcsp.com/example-framework.js",
"destination": "script",
"reportOnly": false
}
}Le champ reportOnly vous dit quel mode a produit le report : true pour le header report-only, false une fois que vous imposez. Le blockedURL est le script qui manquait de SRI valide, c'est la ligne sur laquelle vous agissez.
Le cas de la supply-chain
C'est là que le header justifie sa place. Disons que vous chargez un script d'analytics depuis un CDN avec un hash integrity correct, et que le compte du CDN est compromis, si bien que le fichier est remplacé par une version altérée. SRI attrape celui-là parce que les octets ne correspondent plus au hash, et le script est bloqué.
Disons maintenant qu'un coéquipier ajoute un nouveau tag tiers et oublie l'attribut integrity. SRI par élément ne peut pas aider, il n'y a aucun hash à vérifier. Integrity-Policy le fait : le script sans hash viole la politique, donc il est bloqué et signalé comme integrity-violation. Le même report se déclenche quand une ressource est demandée en mode no-cors, où le navigateur ne peut pas lire les octets pour les vérifier du tout. Les deux sont les écarts de supply-chain que vous voulez connaître avant qu'ils ne s'exécutent.
Integrity-Policy est la moitié application. Savoir ce qui tourne réellement sur vos pages est l'autre moitié. CentralCSP construit un inventaire de scripts à partir des reports de hash CSP, pour que vous voyiez chaque script (et lesquels manquent d'intégrité) avant de basculer le header en imposition. Commencez gratuitement pour cartographier vos scripts côté client et collecter les reports integrity-violation au même endroit.
