Introduction
Utiliser un CDN pour distribuer des contenus est dans certains cas une très bonne pratique, cela permet :
- de mutualiser des ressources utilisées sur plusieurs sites ;
- de permettre de les distribuer « au plus près » des visiteurs de vos sites ;
- et également d’économiser de la bande passante pour tous les sites concernés.
Toutefois, cela comporte un risque. Si un attaquant prenait le contrôle du CDN et en profitait pour insérer du code malveillant dans certaines bibliothèques… instantanément, des centaines voire des milliers de sites pourraient :
- être soit eux-mêmes attaqués par ce code malveillant ;
- ou contribuer malgré eux à « infecter » leurs visiteurs.
Certaines bibliothèques ou frameworks sont massivement utilisées sur les sites web [1], ce risque est donc bien réel : la question de la confiance en un CDN externe est légitime [2].
Ce risque peut toutefois être bien atténué grâce à une spécification du W3c.
SubResource Integrity
C’est là qu’entre en jeu SRI, pour SubResource Integrity, en bon français le « contrôle d’intégrité des sous-ressources ». L’idée – comme son nom l’indique – est de vérifier l’intégrité de ressources, et ce, qu’elles soient sur un CDN ou ailleurs. L’objectif est de veiller à ce qu’aucun tiers n’injecte de contenu ou n’effectue aucune modification sur les ressources en question.
Historiquement, les discussions sur SRI ont commencé début 2014, le premier brouillon public de travail est sorti le 6 octobre 2015, et la spécification est devenue une recommandation officielle du W3c le 23 juin 2016.
Le concept de vérifier l’intégrité de ressources n’est vraiment pas nouveau dans le milieu de l’informatique, les personnes habituées des téléchargements des distributions Linux voient depuis très longtemps ce genre d’informations lors d’un téléchargement d’une image ISO :
Voyons donc comment mettre cela en œuvre maintenant sur nos sites.
Mise en œuvre de SRI
Mettre en place SRI est très simple : il suffit d’indiquer un attribut integrity
sur les balises script
et/ou link
– les seules supportées pour le moment – qui contiendra la valeur de contrôle d’intégrité du fichier (via une « fonction de hachage cryptographique », que nous appellerons un hash pour simplifier).
Cette valeur commence par au moins une chaîne (il peut y avoir plusieurs valeurs d’intégrité spécifiées, séparées par des espaces), chaque chaîne comprenant :
- un préfixe indiquant l’algorithme utilisé (actuellement, les préfixes autorisés sont
sha256
,sha384
etsha512
) ; - suivi d’un tiret…
- …et se terminant par le hash proprement dit (encodé en base64).
Par exemple, cela nous donnerait :
integrity="sha384-yC7kyQdHbdC5s22r6nKzQXwcHKCLKBeg/XRG6mPMTyAUyT8f3htNhtQdFQnhBld5"
et cela s’intègrerait donc ainsi :
<script src="un-script.js" integrity="sha384-yC7kyQdHbdC5s22r6nKzQXwcHKCLKBeg/XRG6mPMTyAUyT8f3htNhtQdFQnhBld5"></script>
Cette valeur peut se calculer de plusieurs manières. Soit à la ligne de commande :
cat FILENAME.js | openssl dgst -sha384 -binary | openssl enc -base64 -A
Ou par exemple en PHP en supposant que $input
soit le contenu du fichier :
echo base64_encode(hash('sha384', $input, true));
Note : pour calculer l’intégrité avec d’autres langages, Generating Subresource Integrity Checksums liste quelques exemples. Des outils permettent également de le calculer comme SRI hash ou de tester leur présence, comme SRI test, Mozilla Observatory ou encore Hardenize.
Note : si vous êtes familier de Content Security Policy, c’est sensiblement le même principe pour les hash.
Exemples simples en pratique
Voici deux exemples volontairement très simples :
En détail, voila ce qu’il s’est passé :
- le navigateur télécharge les ressources ;
- il détecte l’utilisation de SRI sur la feuille de style ;
- il calcule donc l’intégrité du fichier en question, et la compare aux valeurs proposées dans les deux exemples :
- dans le premier cas, la valeur correspond, la feuille de styles est appliquée…
- …et dans le second la valeur ne correspond pas, la feuille de style est purement et simplement ignorée.
Quelques exemples de bibliothèques proposant SRI
Si vous utilisez par exemple Bootstrap via un CDN, vous utilisez peut-être SRI sans même le savoir :
JQuery propose aussi SRI sur son CDN :
Vous noterez sur ces exemples l’utilisation de l’attribut crossorigin="anonymous"
. Cet attribut permet d’indiquer que les requêtes CORS pour cet élément auront la balise de certificat vide [3]. De son côté, le CDN pourra indiquer avec un en-tête HTTP Access-Control-Allow-Origin: *
que la ressource peut être accédée de n’importe quel domaine de manière croisée (cross-site).
Support
Au moment de la mise à jour de cet article (soit le 11 Janvier 2018), le support de SRI selon « Can I use » est le suivant :
Chrome, Opera, Safari et Firefox le supportent pleinement, cela arrive dans la prochaine version d’Edge et certains Webkits sont en train de le prendre en considération (sous iOS cela peut être activé, sans toutefois l’être par défaut). Toujours selon Can I use, SRI est donc supporté par environ 65% du parc des navigateurs, et son emploi ne gênera pas les navigateurs qui ne le supportent pas.
Il n’y a donc aucun souci pour le déployer massivement.
Avenir de SRI
Comme indiqué dans la spécification :
A future revision of this specification is likely to include integrity support for all possible subresources, i.e., a
, audio
, embed
, iframe
, img
, link
, object
, script
, source
, track
, and video
elements.
Traduit en français, cela donne :
Une prochaine révision de cette spécification est susceptible d’inclure le support du contrôle d’intégrité pour toutes les sous-ressources possibles, c’est-à-dire pour les élémentsa
,audio
,embed
,iframe
,img
,link
,object
,script
,source
,track
, etvideo
.
Ajoutons à cela que CSP va bientôt proposer dans son niveau 3 de définir explicitement votre politique de sécurité concernant les ressources, par exemple, il sera possible d’indiquer au navigateur :
Content-Security-Policy: require-sri-for script style;
Autrement dit, il sera possible de dire au navigateur de refuser l’exécution de scripts ou de styles qui n’ont pas de contrôle d’intégrité des ressources ! Même si l’idée de SRI est à la base destinée aux contenus chargés via CDNs, pourquoi ne pas étendre cette idée ? Une fois la page envoyée chez l’agent utilisateur, on ne contrôle pas nécessairement ce qu’il peut s’y passer [4], dans des cas avancés de besoins de sécurité, SRI et CSP pourraient être utilisés conjointement pour garantir que ce qui va s’exécuter chez l’agent utilisateur n’ait pas été modifié.
Bien entendu, cela suppose que la page en question fonctionne en amélioration progressive avec JavaScript désactivé, et que le processus de hash soit exécuté de manière indépendante de l’affichage de la page… à bon entendeur !
Conclusion
SubResource Integrity apporte une sécurité non négligeable, ce n’est pas un hasard si des outils comme Mozilla Observatory ou Hardenize recommandent son utilisation. Comme les navigateurs ne le supportant pas n’en auront cure, et que bon nombre de projets le proposent sur divers CDNs, vous n’avez plus d’excuse pour ne pas l’adopter, l’utiliser et/ou même le déployer vous-mêmes.
Vos commentaires
Suivre les commentaires : |