Comment détecter et atténuer efficacement les attaques Trojan Source dans les bases de code JavaScript avec ESLint
10 novembre 2021
0 minutes de lectureLe 1er novembre 2021, la publication d’un article intitulé Trojan Source: Invisible Vulnerabilities a décrit comment des acteurs malveillants pouvaient utiliser des caractères de contrôle bidirectionnels Unicode pour insérer du code source malveillant dans une base de code apparemment inoffensive. Cette attaque repose sur la confusion des personnes chargées de la revue, qui prennent le code source malveillant obfusqué pour des commentaires.
Qu’est-ce qu’une attaque Trojan Source ?
Les éditeurs de code traditionnels et les pratiques de revue de code ne détectent pas les caractères bidirectionnels présents dans le code source. Des acteurs malveillants peuvent ainsi injecter du code malveillant qui semble inoffensif. Cette vulnérabilité a été rendue publique le 1er novembre 2021 et s’est vu attribuer le CVE-2021-42574.
Voici un extrait affiché dans VS Code illustrant une attaque Trojan Source dans du code source JavaScript :
Et avec cette capture d’écran ?

Avez-vous repéré le problème dans le code source ci-dessus ? Si ce n’est pas le cas, examinez l’extrait de code d’un peu plus près.
Voici ce qui se passe : il s’agit d’une attaque de type Stretched String. Le code de la ligne 3 donne l’impression que l’expression conditionnelle vérifie si la variable accessLevel est égale à la valeur user. Un commentaire en fin de ligne semble évoquer des vérifications logiques et paraît inoffensif, mais la réalité est tout autre.
En réalité, l’utilisation de caractères bidirectionnels Unicode à la ligne 3 dissimule la véritable valeur de chaîne utilisée lors de la vérification de la variable accessLevel. Voici la véritable ligne 3, telle qu’elle est interprétée par le compilateur :
L’article décrit plusieurs façons d’exploiter les caractères de contrôle bidirectionnels pour injecter du code malveillant dans une source : Commenting-Out, Stretched String, Invisible Functions et Homoglyph Function. Les chercheurs ont fourni des exemples JavaScript de toutes ces attaques dans le dépôt trojan-source sur GitHub.
Bien que l’utilisation de caractères de contrôle bidirectionnels soit une approche novatrice, ce type d’attaque n’est pas nouveau : il a déjà été évoqué dans des listes de diffusion et des forums de discussion. On peut notamment citer cette discussion Golang de 2017 sur l’interdiction des caractères RTL/LTR, ou encore cette entrée Bugzilla de 2011 intitulée [BiDi] Misleading display of bidirectional strings when RLO, LRO or PDF is used (à consulter via Google Cache).
Comment corriger les attaques Trojan Source ?
Les auteurs de l’article universitaire estiment que le problème vient des éditeurs de code et des IDE, qui devraient être corrigés pour rendre ces caractères Unicode visibles, ainsi que des compilateurs, qui devraient avertir les utilisateurs de leur présence.
Détecter les attaques Trojan Source dans le code source
Vos outils et processus de modification et de revue de code utilisent peut-être des plateformes qui ne mettent pas en évidence ces caractères bidirectionnels Unicode dangereux. Il se peut donc que votre base de code en contienne déjà.
Comment savoir si votre code source contient des caractères bidirectionnels Unicode ? Pour vous aider, j’ai créé un package npm appelé anti-trojan-source qui analyse un répertoire ou lit les données depuis l’entrée standard (STDIN) afin d’y repérer ces caractères Unicode éventuellement présents dans le texte.
Vous pouvez utiliser npx pour analyser des fichiers comme suit :
Ou, si vous souhaitez l’utiliser comme bibliothèque dans un projet JavaScript :
Prévenir les attaques Trojan Source en JavaScript avec ESLint
Note de la rédaction : Depuis la publication initiale de cet article, des règles contre Trojan Source ont été ajoutées à Snyk Code. Pour en savoir plus, consultez notre article How to prevent Trojan Source attacks with Snyk Code.
Mais mieux encore que de repérer les problèmes existants, c’est de protéger proactivement votre base de code pour empêcher toute attaque Trojan Source d’y être introduite. Dans la communauté JavaScript, nous nous appuyons souvent sur ESLint et ses différents plugins pour faire respecter les normes de qualité et de style du code.
Avec eslint-plugin-anti-trojan-source, vous pouvez désormais ajouter un plugin ESLint pour éviter que vos développeurs, vos systèmes d’intégration continue ou vos processus de build ne fusionnent par erreur du code potentiellement malveillant en raison de caractères bidirectionnels Unicode.
Voici un exemple de configuration ESLint pour un projet JavaScript :
Et voici un exemple de résultat pour un extrait de code vulnérable qui s’est retrouvé dans la base de code :
Comment l’écosystème lutte-t-il contre les attaques Trojan Source ?
Des IDE comme VS Code ont publié des versions qui mettent en évidence ces caractères Unicode, afin que les développeurs les remarquent et puissent les interpréter correctement lors de la revue et de la modification du code. De même, GitHub a publié des avertissements : les bases de code affichées sur GitHub mettent désormais en évidence l’utilisation de ces caractères Trojan potentiellement dangereux lorsqu’elles contiennent des caractères bidirectionnels :

Cependant, sachez que GitHub ne met pas en évidence tous les types d’attaques par logiciel malveillant Trojan. Prenons par exemple le cas présenté dans l’article et baptisé Invisible Functions :

Comme vous pouvez le voir dans l’extrait de code JavaScript ci-dessus, GitHub n’affiche aucun avertissement lors de la revue de ce code. Que se passe-t-il réellement ?
La déclaration de fonction à la ligne 7 contient en réalité un caractère de contrôle Unicode d’espace sans chasse, identifié par U200B, qui donne visuellement l’impression qu’il s’agit d’une fonction légitime function isAdmin().
Nous pouvons le vérifier en affichant le code avec un outil comme bat, un clone de l’outil UNIX cat offrant une meilleure coloration syntaxique et une intégration Git :

Les compilateurs et les environnements d’exécution doivent-ils atténuer les attaques Trojan Source ?
Qu’en est-il des compilateurs et des environnements d’exécution des langages ? La plupart des langages, y compris Node.js, ont choisi de ne pas modifier leur compilateur pour qu’il rejette les caractères Unicode. Le risque est ainsi transféré aux éditeurs de code et aux personnes, qui doivent redoubler de vigilance lorsqu’elles lisent du code et effectuent des revues de code.
Cela dit, certains environnements d’exécution, comme Zig, envisagent favorablement de déclencher une erreur de compilation en cas de détection de caractères bidirectionnels Unicode dans le code source, tout en permettant de contourner ces erreurs au moyen d’un commentaire explicite.
Ressources sur les attaques Trojan Source
J’espère que cet article vous a aidé à comprendre les attaques Trojan Source et la manière dont elles peuvent se manifester dans l’écosystème JavaScript. Pour en savoir plus sur ces attaques, je vous recommande les ressources suivantes :
Article de blog : comment prévenir les attaques Trojan Source avec Snyk Code
Site officiel de Trojan Source : https://www.trojansource.codes
Dépôt officiel de Trojan Source avec des exemples de code et des preuves de concept : https://github.com/nickboucher/trojan-source
Article officiel annonçant Trojan Source : https://www.lightbluetouchpaper.org/2021/11/01/trojan-source-invisible-vulnerabilities
Sécurisez votre code grâce à des informations de pointe
Découvrez toutes les fonctionnalités SAST de Snyk Code en seulement 30 minutes.


