Intégrité des sous-ressources (Subresource Integrity)
L'intégrité des sous-ressources (Subresource Integrity en anglais, aussi abbrégé SRI) est une fonctionnalité de sécurité qui permet aux navigateurs de vérifier que les ressources qu'ils récupèrent (par exemple, depuis un CDN) sont délivrées sans manipulation inattendue. Elle fonctionne en vous permettant de fournir un hachage cryptographique auquel la ressource récupérée doit correspondre.
Note : Pour la vérification de l'intégrité d'une sous-ressource servie depuis une origine différente de celle du document dans lequel elle est intégrée, les navigateurs vérifient également la ressource à l'aide du partage des ressources entre origines (CORS), afin de s'assurer que l'origine qui sert la ressource autorise son partage avec l'origine demandeuse.
Comment l'intégrité des sous-ressources aide
Les sites web choisissent parfois de s'appuyer sur un tiers tel qu'un réseau de diffusion de contenu (CDN) pour héberger certaines de leurs ressources, plutôt que d'héberger toutes leurs ressources eux-mêmes. Par exemple, un document servi depuis https://example.com peut inclure une ressource provenant d'un autre emplacement :
<script src="https://not-example.com/script.js"></script>
Cela comporte un risque : si un·e attaquant·e prend le contrôle de l'hébergeur tiers, il·elle peut injecter du contenu malveillant arbitraire dans ses fichiers (ou remplacer complètement les fichiers) et peut donc potentiellement attaquer les sites qui récupèrent des fichiers depuis cet hébergeur.
L'intégrité des sous-ressources vous permet d'atténuer certains risques d'attaques de ce type, en garantissant que les fichiers récupérés par votre application ou document web ont été délivrés sans qu'un·e attaquant·e ait injecté de contenu supplémentaire dans ces fichiers — et sans qu'aucune autre modification n'ait été apportée à ces fichiers.
Utilisation de l'intégrité des sous-ressources
Vous utilisez la fonctionnalité d'intégrité des sous-ressources en définissant un hachage cryptographique encodé en base64 d'une ressource (fichier) que vous demandez au navigateur de récupérer, dans la valeur de l'attribut integrity d'un élément <script> ou d'un élément <link> avec rel="stylesheet", rel="preload" ou rel="modulepreload".
Une valeur d'integrity commence par au moins une chaîne de caractères, chaque chaîne de caractères comportant un préfixe indiquant un algorithme de hachage particulier (actuellement, les préfixes autorisés sont sha256, sha384 et sha512), suivi d'un tiret, et se terminant par le hachage encodé en base64.
Note : Une valeur integrity peut contenir plusieurs hachages séparés par des espaces. Une ressource sera chargée si elle correspond à l'un de ces hachages.
Exemple de chaîne de caractères integrity avec un hachage sha384 encodé en base64 :
sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC
Ici, oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC est la partie « hachage », et le préfixe sha384 indique qu'il s'agit d'un hachage sha384.
Note :
La partie « hachage » d'une valeur integrity est, à proprement parler, un digest cryptographique obtenu en appliquant une fonction de hachage particulière à une entrée (par exemple, un fichier script ou feuille de style). Mais il est courant d'utiliser le terme « hachage » pour désigner un digest cryptographique, c'est donc ce qui est utilisé dans cet article.
Outils pour générer des hachages SRI
Générateur de hachage SRI
Le Générateur de hachage SRI (angl.) est un outil en ligne que vous pouvez utiliser pour générer des hachages SRI.
Utilisation d'OpenSSL
Vous pouvez générer des hachages SRI en ligne de commande avec OpenSSL à l'aide d'une commande comme :
cat FILENAME.js | openssl dgst -sha384 -binary | openssl base64 -A
Sous Windows, vous pouvez créer un outil pour générer des hachages SRI avec le code suivant :
@echo off
set bits=384
openssl dgst -sha%bits% -binary %1% | openssl base64 -A > tmp
set /p a= < tmp
del tmp
echo sha%bits%-%a%
pause
Pour utiliser ce code :
- Enregistrez ce code dans un fichier nommé
sri-hash.batdans le dossier SendTo de votre environnement Windows (par exemple,C:\Users\USER\AppData\Roaming\Microsoft\Windows\SendTo). - Faites un clic droit sur un fichier dans l'Explorateur de fichiers, sélectionnez Envoyer vers…, puis sélectionnez
sri-hash. Vous verrez la valeur d'intégrité dans une fenêtre de commande. - Sélectionnez la valeur d'intégrité et faites un clic droit pour la copier dans le presse-papiers.
- Appuyez sur une touche pour fermer la fenêtre de commande.
Note : Si OpenSSL n'est pas installé sur votre système, consultez le site officiel du projet OpenSSL (angl.) pour obtenir des informations sur le téléchargement et l'installation. Le projet OpenSSL n'héberge pas lui-même de distributions binaires, mais maintient une liste informelle de distributions tierces : https://github.com/openssl/openssl/wiki/Binaries.
Utilisation de shasum
Vous pouvez générer des hachages SRI avec shasum (angl.) à l'aide d'une commande comme :
shasum -b -a 384 FILENAME.js | awk '{ print $1 }' | xxd -r -p | base64
- Le passage par
xxdconvertit la sortie hexadécimale deshasumen binaire. - Le passage par
awkest nécessaire carshasumtransmet le nom du fichier haché dans sa sortie àxxd. Cela peut avoir des conséquences désastreuses si le nom du fichier contient des caractères hexadécimaux valides — carxxdles décodera aussi et les transmettra àbase64.
Partage des ressources entre origines (CORS) et intégrité des sous-ressources
Pour la vérification de l'intégrité d'une sous-ressource servie depuis une origine différente de celle du document dans lequel elle est intégrée, les navigateurs vérifient également la ressource à l'aide du partage des ressources entre origines (CORS), afin de s'assurer que l'origine qui sert la ressource autorise son partage avec l'origine demandeuse. Par conséquent, la ressource doit être servie avec un en-tête Access-Control-Allow-Origin qui autorise le partage avec l'origine demandeuse :
Access-Control-Allow-Origin: *
Fonctionnement de l'intégrité des sous-ressources dans les navigateurs
Les navigateurs gèrent l'intégrité des sous-ressources de la manière suivante :
-
Lorsqu'un navigateur rencontre un élément HTML
<script>ou<link>avec un attributintegrity, avant d'exécuter le script ou d'appliquer une feuille de style définie par l'élément<link>, il doit d'abord comparer le script ou la feuille de style au hachage attendu indiqué dans la valeur de l'attributintegrity.Pour la vérification de l'intégrité d'une sous-ressource servie depuis une origine différente de celle du document dans lequel elle est intégrée, les navigateurs vérifient également la ressource à l'aide du partage des ressources entre origines (CORS), afin de s'assurer que l'origine qui sert la ressource autorise son partage avec l'origine demandeuse.
-
Si le script ou la feuille de style ne correspond pas à la valeur
integrityassociée, le navigateur doit refuser d'exécuter le script ou d'appliquer la feuille de style, et doit à la place retourner une erreur réseau indiquant que la récupération de ce script ou de cette feuille de style a échoué.
Politique d'intégrité
Les en-têtes HTTP Integrity-Policy et Integrity-Policy-Report-Only permettent à un document d'imposer une politique concernant les exigences de métadonnées d'intégrité sur les sous-ressources scripts et feuilles de style chargées.
Lorsqu'un en-tête Integrity-Policy est défini, le navigateur bloque les requêtes en mode no-cors ou sans attribut integrity, et signale également les violations si un point de rapport valide est défini.
Lorsqu'un en-tête Integrity-Policy-Report-Only est défini, le navigateur autorise les requêtes qui violent la politique, mais signale les violations au point de rapport (si un point de rapport valide est défini).
Les développeur·euse·s utilisent généralement Integrity-Policy-Report-Only comme première étape de déploiement de leur politique d'intégrité, afin de s'assurer que tous les scripts et feuilles de style chargés dans leurs documents possèdent les métadonnées d'intégrité appropriées. Une fois qu'aucun rapport de violation n'est reçu, ils·elles peuvent activer le blocage avec l'en-tête Integrity-Policy sans risquer de casser l'expérience utilisateur.
Les valeurs d'en-tête sont définies comme des dictionnaires de champs structurés avec les clés suivantes :
blocked-destinations-
Définit une liste de destinations de requête à bloquer. Les seules valeurs autorisées sont
scriptetstyle. sourcesFacultatif-
Définit une liste de sources d'intégrité. La valeur par défaut et seule actuellement prise en charge est
inline. Par conséquent, ajoutersources=(inline)à l'en-tête a un effet similaire à l'omission desources. endpointsFacultatif-
Définit une liste de points de rapport. Les points de rapport doivent être définis dans un en-tête
Reporting-Endpoints.
Lorsqu'une requête est bloquée par une politique d'intégrité, un rapport de violation de l'API Reporting est créé avec un type integrity-violation et un corps de type IntegrityViolationReportBody qui inclut des informations telles que l'URL du document et la ressource bloquée.
Un rapport typique peut ressembler à ceci :
{
"type": "integrity-violation",
"url": "https://example.com",
"body": {
"documentURL": "https://example.com",
"blockedURL": "https://example.com/main.js",
"destination": "script",
"reportOnly": false
}
}
Exemples
Dans les exemples suivants, on suppose que oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC est déjà connu comme étant le hachage SHA-384 attendu (digest) d'un script particulier example-framework.js, et qu'une copie du script est hébergée à https://example.com/example-framework.js.
Intégrité des sous-ressources avec l'élément <script>
Vous pouvez utiliser l'élément HTML <script> suivant pour indiquer au navigateur qu'avant d'exécuter le script https://example.com/example-framework.js, il doit d'abord comparer le script au hachage attendu et vérifier qu'il y a correspondance.
<script
src="https://example.com/example-framework.js"
integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
crossorigin="anonymous"></script>
Note :
Pour plus de détails sur l'attribut crossorigin, voir Attributs de configuration CORS.
Application de l'intégrité avec l'en-tête Integrity-Policy
Vous pouvez ajouter l'en-tête Integrity-Policy à votre document pour garantir que les ressources externes qu'il charge (dans ce cas, des scripts) sont chargées avec intégrité (et ne sont pas chargées en mode no-cors).
Integrity-Policy: blocked-destinations=(script), endpoints=(integrity-endpoint, some-other-integrity-endpoint)
Si vous n'êtes pas certain·e que tous les scripts externes possèdent des métadonnées d'intégrité, vous pouvez activer la version « rapport uniquement » de la fonctionnalité et commencer à recevoir des rapports de violation.
Vous pouvez le faire avec l'en-tête Integrity-Policy-Report-Only.
Integrity-Policy-Report-Only: blocked-destinations=(script), endpoints=(integrity-endpoint, some-other-integrity-endpoint)
Spécifications
| Specification |
|---|
| HTML> # attr-link-integrity> |
| HTML> # attr-script-integrity> |
| Subresource Integrity> # the-integrity-attribute> |