Les scripts tiers sont un risque de chaîne d’approvisionnement
Un script tiers est du code que vous n’avez pas écrit, servi par une entreprise que vous ne contrôlez pas, s’exécutant dans vos pages avec les sessions de vos utilisateurs : en termes de chaîne d’approvisionnement, c’est une dépendance qui peut changer son propre code à tout moment, sans publication, sans relecture et sans avertissement. En octobre 2026, ce risque abstrait est devenu une perte concrète, selon les récits, lorsqu’un script de surveillance de performance chargé par un grand site de négociation a été échangé contre un autre construit pour drainer ses utilisateurs. Cet article parcourt ce qui a été rapporté, ce que Subresource Integrity arrête réellement, pourquoi épingler une version précède le calcul de son hash, quand l’auto-hébergement est la meilleure réponse, et la courte routine d’audit qui garde l’inventaire honnête.
Ce qui s’est passé chez Polymarket, selon les récits
Le 29 octobre 2026, selon les récits, le site international de Polymarket a mis la négociation en mode annulation uniquement après que des utilisateurs ont signalé des fonds quittant leurs comptes, et la négociation a repris environ une heure plus tard. Les propres déclarations de l’entreprise, selon les récits, ont attribué l’incident à un fournisseur tiers compromis, ont dit que l’affaire avait été transmise aux forces de l’ordre et ont promis de dédommager intégralement les utilisateurs touchés. Les rapports fondés sur l’analyse post-incident de l’entreprise, du 30 octobre, ont chiffré le montant pris dans l’attaque à environ 2,7 millions de dollars, avec des remboursements totaux de 3,9 millions une fois inclus les paiements de bonne volonté pour les pertes causées par la pause de la négociation ; des analyses indépendantes sur la chaîne, citées dans la couverture, ont tracé un chiffre similaire, autour de 2,7 millions, réparti sur plusieurs centaines de portefeuilles. Aucun de ces chiffres n’est vérifié de façon indépendante ici : ce sont les chiffres des récits, et cet article les traite comme tels.
Le mécanisme, selon les récits, est la partie qui se généralise. Les chercheurs cités dans la couverture ont lié le code malveillant au script de surveillance des utilisateurs réels (RUM) d’un fournisseur de performance web — un petit fichier dont le seul travail est de mesurer la vitesse de chargement des pages dans les navigateurs des visiteurs, intégré par client depuis le CDN du fournisseur. Ce fichier, selon les récits, a été remplacé par une charge écrite spécifiquement pour le site cible : elle travaillait au sein de sessions connectées, utilisait la machinerie de négociation propre au site déjà présente dans la page, et déplaçait positions et fonds vers une destination contrôlée par l’attaquant. Selon les récits, aucune faille de contrat intelligent ni aucun mot de passe ou clé privée volé n’étaient en jeu — le script échangé était simplement la page, pour ce qui est du navigateur. Que chaque détail de ce récit survive à un examen ultérieur est, pour la leçon, à côté du sujet : la forme de l’attaque — un fichier fournisseur, échangé une fois, exécuté par chaque visiteur — est la forme standard de cette classe d’incidents.
Un script tiers est votre code, avec le processus de publication d’un autre
Il n’y a pas de bac à sable dans une balise script classique. Le code chargé depuis le CDN d’un fournisseur s’exécute dans votre origine avec le même accès que votre propre paquet : il peut lire et changer le DOM, lire les valeurs de formulaire au fil de la frappe, appeler vos API avec la session de l’utilisateur et envoyer ce qu’il trouve n’importe où. Le guide OWASP sur le JavaScript tiers nomme les trois risques sans détour — perte de contrôle sur les changements de l’application cliente, exécution de code arbitraire sur les systèmes clients, et divulgation d’informations sensibles à des tiers — et les trois découlent de ce seul fait. Votre processus de relecture, votre gel de code et votre comité de changement s’arrêtent à votre propre construction ; le fichier du fournisseur peut être édité par le fournisseur, par un attaquant qui compromet le fournisseur, ou par quiconque réenregistre le domaine du fournisseur s’il expire un jour.
Cette asymétrie est la raison pour laquelle « nous faisons confiance à ce fournisseur » n’est pas un contrôle. La confiance décide de qui est le script que vous acceptez aujourd’hui ; elle ne dit rien de ce que cette URL servira demain, et elle ne vous donne aucun signal lorsque le contenu change. Les contrôles qui fonctionnent sont ceux qui retirent la confiance (servir le fichier vous-même), la restreignent (une Content-Security-Policy qui limite ce que tout script peut faire et où il peut envoyer des données) ou la vérifient mécaniquement à chaque chargement — ce à quoi sert Subresource Integrity. Commencez par l’inventaire : vous ne pouvez appliquer aucun des trois à des scripts que vous ne savez pas avoir, et la plupart des sites en ont plus que leurs propriétaires ne l’attendent une fois comptées les balises marketing, les widgets de support et les codes de surveillance.
Ce que SRI arrête — et ce qu’il n’arrête pas
Subresource Integrity est un mécanisme de navigateur, spécifié par le W3C et documenté par MDN : la page déclare le hash cryptographique du fichier qu’elle attend dans l’attribut integrity de la balise, le navigateur calcule le hash de ce qu’il a réellement téléchargé et, à la moindre différence, refuse d’exécuter le fichier. Pour un fichier d’une autre origine, la balise a aussi besoin de crossorigin="anonymous" et le serveur doit envoyer des en-têtes CORS, pour que le navigateur soit autorisé à faire le contrôle. Appliqué à une bibliothèque fixe, SRI convertit un échange silencieux en échec bruyant : le fichier qui arrive est soit, octet pour octet, le fichier que vous avez relu, soit il ne s’exécute pas du tout. Si le script de surveillance de l’incident rapporté avait été un fichier fixe chargé de cette manière, une charge échangée aurait échoué au contrôle au lieu de s’exécuter dans les sessions des utilisateurs — ce conditionnel est la forme honnête de l’affirmation, car savoir si ce code précis était susceptible de hash est une question portant sur un fichier dynamique par client, qui est exactement le cas difficile ci-dessous.
Ce que SRI n’arrête pas est tout aussi important. Il n’aide pas pour les scripts dont le contenu est censé changer — conteneurs de gestionnaires de balises, chargeurs de personnalisation et de consentement, fichiers générés par client — car il n’y a aucun hash stable à épingler. Il ne juge pas le fichier dont vous avez calculé le hash : un script livré fidèlement peut rester curieux, négligent ou malveillant par conception, et SRI le vérifiera volontiers pour toujours. Il ne couvre pas les scripts injectés à l’exécution par d’autres scripts, il ne protège pas les fichiers internes servis depuis votre propre infrastructure, et il ne fait rien des données qu’un script légitime recueille une fois qu’il s’exécute. SRI est une garantie mécanique — ces octets exacts, ou rien — et il gagne sa place à côté de CSP, de la relecture des fournisseurs et de la minimisation du nombre de tiers qui obtiennent un accès au niveau session dès le départ, et non à leur place. Le contrôle des en-têtes de sécurité de ce site note le côté CSP de cette paire.
Épinglez la version, ou le hash ne pourra pas tenir
SRI a une condition préalable qui fait échouer plus d’audits que la malveillance : l’URL doit toujours renvoyer les mêmes octets. Un hash épinglé sur une adresse latest, une version majeure flottante ou un fichier par client que le fournisseur régénère est un hash qui se brise dès la première mise à jour du fournisseur — et les équipes qu’un échec SRI auto-infligé a réveillées une fois tendent à retirer l’attribut plutôt qu’à réparer l’adresse, laissant la page pire que non mesurée. L’ordre durable est l’inverse : changez d’abord l’URL pour qu’elle nomme la version exacte ([email protected], /v2.4.0/), relisez cette version une fois, puis calculez le hash de ce fichier exact. Les montées de version deviennent alors des événements délibérés — nouvelle URL, nouveau hash, un commit — au lieu de changements ambiants que vous découvrez par vos utilisateurs.
Épingler a un coût, et l’honnêteté exige de le nommer : une bibliothèque épinglée ne reçoit plus les correctifs de sécurité silencieux du fournisseur, donc épingler crée le devoir de suivre les publications et de monter de version à dessein, le même devoir que porte toute dépendance vendue avec le code. C’est un devoir gérable — les notes de version et un rappel de calendrier le couvrent — et il est strictement meilleur que l’alternative qu’il remplace, dans laquelle les mises à jour arrivent non relues au rythme du fournisseur et les ruptures arrivent non annoncées au vôtre. Traitez la paire comme une seule pratique : l’épinglage rend le contenu adressable, le hash le rend vérifiable, et l’audit s’assure qu’aucun des deux n’a pourri en silence — une chaîne de version éditée hors du code par une migration de CMS est aussi courante qu’un hash absent, et seulement un peu plus difficile à remarquer à l’œil nu.
L’auto-hébergement, et la routine d’audit
Pour les scripts qui comptent le plus, il existe une option plus franche : servir le fichier vous-même. L’auto-hébergement retire complètement le serveur, le compte et le domaine du fournisseur de votre chaîne d’approvisionnement à l’exécution, laisse votre canal de déploiement normal relire et hasher le fichier, et continue de fonctionner lorsque le CDN du fournisseur ne fonctionne pas. Les compromis sont réels — vous abandonnez le cache de bordure du fournisseur et les mises à jour automatiques, vous prenez le devoir de livrer vous-même ses correctifs de sécurité, et les licences de certains fournisseurs ou leurs fichiers générés par client ne le permettent tout simplement pas — donc le partage sensible se fait par criticité : auto-hébergez les petites bibliothèques fixes sur les pages sensibles ; épinglez et hashez ce qui reste sur un CDN ; gouvernez (avec restrictions de publication, relecture des changements et CSP) les balises dynamiques qui ne peuvent être ni épinglées ni hébergées ; et supprimez, à vue, tout script que personne ne peut justifier. Chaque script retiré est une chaîne d’approvisionnement que vous n’avez plus.
La routine qui garde cela vrai est assez courte pour être réellement exécutée. Chaque trimestre — et après tout refonte, migration de CMS ou nouveau fournisseur — lancez l’audit des scripts tiers et SRI sur vos gabarits de pages clés : il liste chaque script auquel le HTML statique fait référence, lesquels sont tiers, lesquels manquent d’intégrité et lesquels ne sont pas épinglés, et calcule un sha384 prêt à coller pour les premiers hashs manquants qu’il peut récupérer. Corrigez par ordre d’impact — les pages de session, de paiement et de données personnelles d’abord —, puis vérifiez les couches transport et en-têtes avec l’évaluateur SSL et le contrôle des en-têtes, et terminez dans le gestionnaire de balises, dont les scripts injectés à l’exécution échappent à un audit statique : passez sa liste de publieurs et son historique de changements en revue avec la même suspicion que vous donneriez à un journal de déploiements. Quinze minutes par trimestre, face à une classe d’incidents dont le coût rapporté, dans le cas ci-dessus, s’est chiffré en millions en environ une heure.