EN
Sécuriser son domaine

Scripts tiers et supply chain côté navigateur

Chaque script externe chargé par votre site s'exécute avec la confiance de vos visiteurs. Risques supply chain, SRI et auto-hébergement.

1 Introduction

Quand votre page d'accueil s'ouvre, le navigateur ne charge pas un fichier mais des dizaines : votre HTML et vos images, mais aussi un outil d'analytics, un widget de chat, des polices d'un service de fonts, une bibliothèque JavaScript depuis un CDN public, un bandeau cookies, un pixel publicitaire. Tout cela vient des serveurs de quelqu'un d'autre, et chaque script parmi eux s'exécute dans votre page avec les mêmes droits que votre propre code.

Chaque script externe est donc un fournisseur qui a les clés de votre site. Si l'un de ces serveurs est piraté, revendu ou simplement abandonné, le code reçu par vos visiteurs change, sans que rien ne bouge de votre côté. Le bloc « Network requests » d'un scan de domaine vous montre qui sont ces fournisseurs.

Juin 2024

Le CDN polyfill.io, racheté par un nouveau propriétaire, se met à servir du code malveillant aux sites qui l'intègrent

100 000+

Sites qui intégraient polyfill.io à ce moment-là, selon les chiffres publiés

1

Attribut HTML, integrity=, suffit pour que le navigateur refuse un fichier modifié

2 Comment ça marche

Une ligne comme <script src="https://cdn.fournisseur.com/widget.js"> demande au navigateur de chaque visiteur de récupérer ce fichier et de l'exécuter, à chaque visite, tel qu'il est maintenant. Vous l'avez regardé une fois en l'ajoutant ; le navigateur, lui, ne le vérifie jamais.

1

Vous l'intégrez

Votre page appelle un script hébergé par un tiers : un CDN, un service d'analytics, l'éditeur d'un widget.

2

Il le modifie

L'éditeur met le fichier à jour, se fait pirater, revend le domaine, ou le laisse expirer et quelqu'un d'autre le rachète.

3

Vos visiteurs l'exécutent

Le nouveau code tourne dans le navigateur de vos visiteurs, sur votre domaine, avec accès à tout ce que contient la page.

Ce qu'un script peut faire dans votre page

Lire chaque champ de formulaire pendant la saisie (mots de passe, numéros de carte, adresses), lire les cookies qui ne sont pas marqués HttpOnly, modifier le contenu de la page, remplacer un RIB sur une page de facture, rediriger le visiteur vers un site de phishing, et envoyer le tout à n'importe quel serveur. Le navigateur le traite comme votre propre code. Les images, polices et feuilles de style sont moins dangereuses (elles n'exécutent pas de code) mais indiquent quand même au tiers qui vous rend visite, et quand.

3 Analyse détaillée

Lire le bloc « Network requests »

La capture se lance à la demande : vous cliquez sur « Load network requests », un navigateur headless ouvre votre page d'accueil (ou toute URL que vous saisissez) et enregistre chaque requête de la page. Elle compte pour un scan de domaine dans votre quota. Chaque ligne donne la méthode, le statut HTTP, le type de ressource (script, stylesheet, font, image, xhr, fetch...), l'URL complète, le type MIME, la taille, la durée et l'IP distante.

Triez par hôte, puis par type

Regroupez les URL par domaine. Les requêtes vers votre domaine sont les vôtres. Tout le reste est un tiers : notez chacun avec sa raison d'être. Regardez en priorité les lignes script : ce sont elles qui exécutent du code.

Les requêtes en échec ne sont pas du bruit

Un script qui échoue parce que son domaine n'existe plus est un risque en sommeil : si quelqu'un rachète ce domaine, votre page exécutera son code. Supprimez la référence sans attendre.

Des hôtes inconnus

Les scripts en chargent souvent d'autres. Un gestionnaire de balises peut appeler une dizaine d'hôtes que vous n'avez jamais ajoutés vous-même. Ils tournent quand même sur votre page : remontez jusqu'à la balise ou au plugin qui les charge.

Ce que le bloc ne vérifie pas

Il liste les requêtes sans les juger, et ne voit que la page chargée. Il ne dit pas si un script utilise SRI ou s'il est autorisé par votre CSP : cela se vérifie dans le code source de la page et dans vos en-têtes, comme expliqué plus bas.

Attaques de supply chain côté navigateur

polyfill.io (2024)

Un service gratuit très répandu, qui fournissait du code de compatibilité pour les vieux navigateurs. Son domaine a changé de mains début 2024, et en juin des chercheurs ont découvert qu'il injectait des redirections malveillantes dans les pages des sites qui l'utilisaient. Ces sites n'avaient rien modifié. Si polyfill.io apparaît dans vos requêtes, retirez-le aujourd'hui : les navigateurs modernes n'en ont presque jamais besoin.

Magecart et le web skimming

« Magecart » désigne les groupes qui injectent du code de vol de cartes bancaires dans les pages de paiement, souvent en compromettant un script tiers plutôt que la boutique elle-même. La fuite de British Airways en 2018, où des données de paiement ont été aspirées sur son site, en est le cas le plus connu.

La leçon

Moins de scripts tiers, c'est moins de fournisseurs capables de vous nuire. Sur les pages sensibles (connexion, paiement, compte), chargez le moins de code externe possible.

Subresource Integrity (SRI)

SRI fige un fichier sur son contenu exact. Vous ajoutez l'empreinte (hash) du fichier dans la balise ; si le serveur envoie un jour autre chose, le navigateur refuse de l'exécuter :

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/library.min.js"
        integrity="sha384-HASH_BASE64_DU_FICHIER"
        crossorigin="anonymous"></script>

Calculez l'empreinte vous-même, à partir du fichier que vous avez relu :

curl -s https://cdn.jsdelivr.net/npm/[email protected]/dist/library.min.js \
  | openssl dgst -sha384 -binary | openssl base64 -A

Fixez une version, jamais « latest »

SRI ne fonctionne que sur un fichier qui ne change pas : l'URL doit contenir une version précise. Une URL qui sert toujours la dernière version cassera l'empreinte à la prochaine mise à jour.

crossorigin="anonymous" est obligatoire

Pour un fichier hébergé sur un autre domaine, le navigateur ne peut vérifier l'empreinte que si la requête passe par CORS. Sans l'attribut, la vérification est impossible et le fichier est bloqué.

Là où SRI ne s'applique pas

Les balises d'analytics, les SDK de paiement et les widgets de chat changent leur fichier volontairement, parfois chaque jour : une empreinte les casserait. Pour ceux-là, on fait confiance à l'éditeur, on les limite avec la CSP, et on les retire des pages où ils ne servent à rien.

Auto-hébergement et Content-Security-Policy

Hébergez vous-même ce que vous pouvez

Une bibliothèque ou une police copiée sur votre serveur ne peut pas être modifiée par un tiers, ne signale pas vos visiteurs à quelqu'un d'autre et supprime un fournisseur. En échange, ses mises à jour vous reviennent : suivez-les avec vos autres dépendances.

Limitez les origines avec la CSP

Un en-tête Content-Security-Policy liste les hôtes autorisés à servir des scripts. Tout le reste est bloqué, y compris un script injecté plus tard. Commencez par Content-Security-Policy-Report-Only pour voir ce qui casserait, puis appliquez.

Content-Security-Policy: script-src 'self' https://cdn.jsdelivr.net https://www.googletagmanager.com; object-src 'none'; base-uri 'self'

L'angle vie privée : traceurs et RGPD

Chaque requête vers un tiers lui transmet l'adresse IP du visiteur et la page consultée. Pour les traceurs et les pixels publicitaires, c'est tout l'objet, et le RGPD exige en général le consentement avant que la requête parte.

Vérifiez ce qui se charge avant le consentement

La capture charge la page sans cliquer sur le bandeau cookies. Tout traceur présent dans la liste se déclenche donc avant consentement. C'est un problème de conformité autant que de sécurité.

Même les polices comptent

En janvier 2022, un tribunal de Munich a jugé que charger Google Fonts depuis les serveurs de Google sans consentement violait le RGPD, puisque l'IP du visiteur partait chez Google. Héberger ses polices règle la question.

Listez les tiers de votre page sur mlab.sh

Un scan de domaine peut charger votre page d'accueil dans un navigateur headless et lister chaque requête, pour voir chaque hôte externe avec lequel le navigateur de vos visiteurs communique.

Scanner votre domaine sur mlab.sh

4 Red Flags

Un script servi par polyfill.io ou un autre hôte compromis connu

Retirez la balise aujourd'hui. Si elle était présente mi-2024, partez du principe que vos visiteurs ont pu recevoir du code malveillant et revoyez ce que la page manipule.

Un script dont le domaine n'existe plus

Quiconque enregistre ce domaine pourra exécuter du code sur votre site. Supprimez la référence maintenant, cela ne coûte rien.

Des scripts tiers sur les pages de connexion ou de paiement

Ces pages manipulent mots de passe et numéros de carte, précisément ce que cherchent les skimmers. Ne gardez que ce dont la page ne peut pas se passer.

Des bibliothèques sur CDN sans integrity=

Un fichier versionné sur un CDN public est le cas le plus simple pour SRI. Ajoutez l'empreinte, ou hébergez le fichier vous-même.

Des traceurs qui partent avant la réponse au bandeau cookies

Un problème RGPD en plus d'un problème de sécurité. Configurez votre outil de consentement pour les bloquer tant que le visiteur n'a pas accepté.

Modules connexes