Les 10 principales vulnérabilités de sécurité JavaScript
JavaScript alimente une grande partie des applications modernes – des frontends web dynamiques aux backends Node.js évolutifs – ce qui signifie qu'il expose également une vaste surface d'attaque. La flexibilité qui rend JavaScript si puissant peut se transformer en une arme à double tranchant lorsque la sécurité est négligée. Le code frontend s'exécute directement dans les navigateurs des utilisateurs (et peut être inspecté ou manipulé par des attaquants), tandis que les applications Node.js backend intègrent souvent d'innombrables packages et gèrent des données sensibles. La triste vérité est qu'une seule ligne JavaScript non sécurisée ou une dépendance vulnérable peut ouvrir la porte aux exploits. En fait, des rapports récents de l'industrie montrent que les applications web continuent d'être truffées de vulnérabilités courantes comme le cross-site scripting et les bibliothèques obsolètes, malgré des années d'avertissements.
Chaque script balise, chaque npm install, et chaque analyse JSON pourrait cacher un risque potentiel. Dans les sections ci-dessous, nous détaillons les dix principales vulnérabilités de sécurité JavaScript (couvrant les problèmes côté client et côté serveur), avec des exemples concrets et des conseils sur la façon de les corriger ou de les prévenir. Des pièges classiques comme le XSS aux technologies de pointe attaques de la chaîne d’approvisionnement, chaque vulnérabilité inclut des étapes d'atténuation et une mention de la manière dont les outils de sécurité modernes (tels que le SAST d'Aikido, détection de secrets, et analyse des dépendances) peuvent aider à détecter les problèmes tôt.
1. Attaques de cross-site scripting (XSS)
Cross-Site Scripting (XSS) is one of the most prevalent vulnerabilities in we11b applications year after year. XSS occurs when an application includes unsanitized user input in a webpage, allowing attackers to inject malicious JavaScript that executes in the browsers of other users. This can lead to session hijacking, defacement, and theft of sensitive data. Even widely used libraries have suffered XSS flaws – for example, a five-year-old jQuery bug (CVE-2020-11023) allowed arbitrary code execution by passing malicious HTML to jQuery’s DOM methods. Unsuspecting developers who included a vulnerable jQuery (<3.5.0) version in their frontend exposed their users to potential XSS, a flaw so serious that U.S. CISA added it to its exploited vulnerabilities catalog in 2025.
Exemple concret : Un attaquant pourrait élaborer un commentaire ou un nom de profil contenant <script> balises sur un forum qui n'échappe pas correctement la sortie. Lorsque d'autres utilisateurs consultent cette page, le script s'exécute dans leur navigateur – peut-être en volant leur cookie de session ou en les usurpant. le rapport de sécurité 2024 de Claranet Trouvé 2 570 instances de XSS (réfléchies et stockées) sur 500 tests d'intrusion, ce qui en fait « l'une des vulnérabilités les plus courantes détectées… au cours des cinq dernières années ». Cela souligne que le XSS reste une menace majeure dans les applications fortement basées sur JavaScript.
Atténuation : Se défendre contre le XSS nécessite une combinaison de bonnes pratiques de codage et de défenses côté navigateur :
- Escape et valider la sortie : Ne jamais injecter d'entrée utilisateur brute dans le HTML. Assainir les entrées dès leur réception et Escape la sortie dans le contexte approprié (HTML, attribut, JavaScript, etc.).
- Utiliser les contrôles des frameworks : Exploitez les frameworks de templating ou frontend (React, Angular, Vue) qui automatiquement Escape ou assainissent le contenu. Évitez d'utiliser des points d'injection dangereux comme
innerHTMLoudocument.writeavec des données dynamiques – utilisez des alternatives plus sûres commetextContent. - Content Security Policy (CSP) : Implémentez un en-tête CSP strict pour restreindre les sources de chargement des scripts. La CSP peut agir comme une seconde ligne de défense en bloquant les scripts non autorisés.
- HttpOnly Cookies et SameSite : Marquez les cookies comme HttpOnly (non accessibles via JS) et utilisez
SameSiteattributs pour rendre certains types d'attaques (comme le cross-site scripting, le vol de cookies ou le CSRF) plus difficiles.
La détection du XSS exige de la vigilance lors des code review et des tests. Les Tests de sécurité des applications statiques (SAST) d'Aikido peuvent signaler les modèles dangereux – par exemple, l'utilisation de innerHTML avec des données fournies par l'utilisateur ou un encodage de sortie manquant dans les templates de serveur. L'analyse des dépendances aide également : Aikido vous alerterait si vous utilisez une ancienne version de bibliothèque connue pour permettre le XSS (comme l'exemple jQuery 3.4.1 ci-dessus) afin que vous puissiez passer à une version corrigée. En intégrant des analyses automatisées dans votre CI/CD, vous pouvez détecter les vulnérabilités XSS tôt, avant les attaquants.
2. Pollution de prototype
La pollution de prototype est une vulnérabilité spécifique à JavaScript qui exploite la nature dynamique des prototypes d'objets. En JavaScript, les objets héritent des propriétés de leur prototype, et si un attaquant peut injecter des propriétés dans Object.prototype, ces propriétés deviennent accessibles dans tous les objets – menant souvent à un déni de service ou même à une exécution de code à distance. De nombreuses bibliothèques populaires ont souffert de CVEs de pollution de prototype. Par exemple, les versions de Lodash antérieures à 4.17.12 présentaient une vulnérabilité dans ses fonctions defaultsDeep et d'autres fonctions qui pouvaient être trompées pour modifier Object.prototype via a crafted payload. Another example is Handlebars.js: versions <4.3.0 allowed template input to alter special properties like __proto__, qui « peut permettre à un attaquant d'exécuter du code arbitraire » sur le serveur (CVE-2019-19919).
Exemple concret : Un attaquant soumet des données JSON à une API avec une charge utile comme {"__proto__": {"admin": true}}. Si l'application fusionne des objets sans protection (par exemple, en utilisant un lodash.merge ou similaire), la chaîne de prototypes est polluée – par conséquent, des vérifications comme if(user.admin) pourrait inopinément renvoyer vrai pour tous les utilisateurs, ou pire, la logique de l'application pourrait être subvertie. Dans certains cas, la pollution de prototype peut être combinée avec d'autres techniques pour exécuter du code. Par exemple, la faille de « prototype poison » dans les templates Handlebars mentionnée ci-dessus pourrait être utilisée pour exécuter du JavaScript côté serveur dans le contexte de l'application.
Atténuation : Pour prévenir la pollution de prototype :
- Mettre à jour les dépendances : Utilisez des versions corrigées des bibliothèques qui ont résolu les bugs de pollution de prototype. Par exemple, mettez à niveau Lodash vers la version >=4.17.20 (qui a corrigé plusieurs CVEs de ce type).
- Validation des entrées : Validez et nettoyez les entrées JSON ou d'objets. Rejetez ou filtrez les clés d'objet nommées
__proto__,constructor, ou des prototypes dans les données. - Fusion d'objets sécurisée : Lors de la fusion d'objets (par exemple, clonage profond ou extension), utilisez des fonctions ou des bibliothèques sécurisées qui ne copient pas les propriétés de prototype. Certaines bibliothèques utilitaires offrent des options pour ignorer les propriétés héritées.
- Mode strict : Bien que ce ne soit pas une solution miracle, le mode strict (
"use strict") peut empêcher certaines actions dangereuses et faciliter la détection des bugs.
La pollution de prototype peut être subtile, mais l'analyse des dépendances est votre alliée ici. Le scanner de dépendances d'Aikido signalera les versions vulnérables connues de bibliothèques comme Lodash, jQuery ou Handlebars qui sont susceptibles de pollution de prototype, afin que vous puissiez les mettre à jour de manière proactive. Côté code, le moteur SAST d'Aikido peut détecter les modèles de fusion d'objets non sécurisée ou l'utilisation de clés d'objet potentiellement dangereuses. En utilisant Aikido pour auditer en continu votre code et vos packages npm, vous obtenez un filet de sécurité pour cette classe de bugs – les détectant pendant le développement plutôt qu'après une violation.
3. Désérialisation non sécurisée
Les failles de désérialisation non sécurisée se produisent lorsqu'une application accepte des données sérialisées non fiables et les désérialise en objets sans validation appropriée. En JavaScript/Node, cela implique souvent des fonctions qui prennent des objets JSON ou JavaScript fournis par l'utilisateur et les « ressuscitent » en objets actifs. Si elle n'est pas gérée avec soin, la désérialisation peut être exploitée pour exécuter du code arbitraire ou manipuler l'état de l'application. Un exemple notoire fut la node-serialize vulnérabilité de package (CVE-2017-5941) : elle permettait aux attaquants de transmettre un objet sérialisé malveillant contenant une expression de fonction immédiatement invoquée (IIFE). Lors de la désérialisation, la fonction s'exécutait sur le serveur, réalisant ainsi une exécution de code à distance.
Exemples concrets : cette question n'est pas théorique, même les principaux frameworks se sont trompés. Fin 2025, une vulnérabilité critique de React/Next.js (baptisée React2Shell, CVE-2025-55182) a été révélée. Elle était liée à la manière dont les composants React Server gèrent les données sérialisées. « Le cœur du problème réside dans une désérialisation non sécurisée », a noté la recherche Akamai, qui a permis aux attaquants d'injecter des clés d'objets malveillantes conduisant à une pollution des prototypes et, finalement, à l'exécution de code à distance sur le serveur. Cela signifie qu'en envoyant une requête HTTP spécialement conçue, un attaquant non authentifié pouvait prendre le contrôle d'un serveur Node.js exécutant du code React vulnérable, un scénario cauchemardesque pour toute DevSecOps .
Atténuation : La prévention de la désérialisation non sécurisée implique une gestion minutieuse des formats de données :
- Préférer les formats sécurisés : Utilisez JSON pour l'échange de données et évitez d'analyser du code ou des fonctions JavaScript provenant de l'entrée client. JSON.parse standard est plus sûr que
eval()ou la désérialisation personnalisée d'objets JS. - Listes blanches et validation : Si vous devez accepter des objets sérialisés, implémentez des schémas stricts ou des listes blanches. N'autorisez que les propriétés et types d'objets attendus. Rejetez toute entrée contenant des clés comme
__proto__ou constructeur qui pourraient être des vecteurs d'exploitation. - Évitez
evaletFunction(): N'utilisez paseval()sur du JSON ou accepter du code JS brut des clients. De même, évitez les bibliothèques qui exécutent des données d'objet (par exemple, évitez d'exécuter automatiquement des fonctions provenant d'une entrée analysée). - Mises à jour des bibliothèques : Restez informé des correctifs de framework. La vulnérabilité React mentionnée ci-dessus a été corrigée par des mises à jour de React/Next – appliquez ces correctifs immédiatement et surveillez les avis pour les bibliothèques Node.js qui effectuent la désérialisation.
La plateforme d'Aikido peut aider à détecter la désérialisation non sécurisée de plusieurs manières. Analyse statique du code vous avertira si votre code utilise des fonctions risquées (comme unserialize() d'une bibliothèque obsolète ou utilisant eval sur l'entrée). Si vous utilisez des paquets connus pour être vulnérables (comme le paquet buggé node-serialize <=0.0.4, or certain versions of React), Aikido’s dependency scanner would flag those by CVE. Additionally, Aikido’s runtime SAST analysis (if integrated in testing) can observe data flows – for example, user input flowing into a dangerous sink – and alert you. The bottom line: integrating such tools in CI means you’d catch something like React2Shell in your code avant de cela devient React2Shell dans l'actualité.
4. Cross-Site Request Forgery (CSRF)
Le Cross-Site Request Forgery (CSRF) est une vulnérabilité web classique qui affecte souvent les applications basées sur JavaScript (ou toute application web avec sessions). Contrairement au XSS, qui exploite l'injection de code, le CSRF exploite la confiance dans le navigateur de l'utilisateur. Il permet à un attaquant de tromper le navigateur d'une victime pour qu'il effectue des requêtes non intentionnelles vers votre application, sous le couvert des propres identifiants de la victime. En termes plus simples, si un utilisateur est connecté à votre site, un attaquant peut potentiellement inciter son navigateur (via un lien ou une image malveillante) à effectuer des actions comme la modification des détails du compte ou l'initiation de transactions sans le consentement de l'utilisateur.
Exemple concret : Un exemple bien connu est le analogie publication de forum/virement bancaire – imaginez une application bancaire où le formulaire de virement est vulnérable au CSRF. Un attaquant pourrait envoyer à un utilisateur connecté un lien (ou intégrer un formulaire à soumission automatique sur une page malveillante) qui déclenche POST /transfer?amount=1000&to=attackerAccount. Si l'application bancaire n'a pas de protection CSRF, le navigateur de l'utilisateur enverra consciencieusement cette requête avec les cookies de session, et la banque l'exécutera en pensant que l'utilisateur l'a initiée. Dans le contexte de JavaScript, les applications monopages (SPA) peuvent s'appuyer sur des API qui utilisent des cookies pour l'authentification ; si ces API n'implémentent pas de défenses CSRF (comme l'exigence d'un jeton ou de cookies same-site), elles sont également exploitables. Même les frameworks qui incluent des jetons CSRF peuvent être mal configurés – par exemple, si le backend d'une application Angular ou React définit une politique CORS trop large ou des drapeaux SameSite manquants, les attaques CSRF peuvent passer inaperçues.
Mesures d'atténuation : Les principales stratégies pour contrer le CSRF incluent :
- Jetons CSRF : Intégrez des jetons imprévisibles dans les formulaires ou les appels d'API et vérifiez-les côté serveur. Les frameworks modernes disposent souvent de middlewares CSRF. Assurez-vous que les jetons sont liés à la session de l'utilisateur et vérifiés à chaque requête modifiant l'état.
- Cookies SameSite : Définissez les cookies de session avec l'
SameSite=LaxouStrictattribut. Cela empêche les navigateurs d'envoyer des cookies lors de requêtes intersites (le mécanisme principal du CSRF). Notamment,Strictpourrait interrompre certains flux légitimes, doncLaxest une valeur par défaut équilibrée pour la plupart des applications. - En-têtes personnalisés et vérification de l'origine : Pour les API (surtout si vous utilisez fetch/XHR dans les SPA), vous pouvez exiger un en-tête personnalisé (par exemple,
X-Requested-With: XMLHttpRequest) et rejeter les requêtes qui ne l'ont pas. De plus, vérifiez l'OriginetRefereren-têtes sur les requêtes sensibles – assurez-vous qu'ils proviennent de votre domaine. - Éviter d'utiliser GET pour les changements d'état : Le CSRF peut utiliser
<img>ou<script>balises pour initier des requêtes GET. Assurez-vous que toute action critique (comme la modification de données) utilise POST (ou d'autres méthodes non-GET), et idéalement nécessite toujours un jeton.
Bien que le CSRF relève davantage de la conception que d'un bug de code, la suite d'outils de sécurité d'Aikido peut néanmoins vous aider. Analyse statique peut détecter les routes ou les contrôleurs dépourvus de protections CSRF si vous utilisez des frameworks courants (par exemple, un manque de csrf() middleware dans une application Express, ou aucun module anti-CSRF n'est utilisé). Aikido peut également analyser vos en-têtes de sécurité HTTP et les configurations de cookies (via l'analyse dynamique ou des scripts de pipeline) pour signaler les manquants SameSite ou HttpOnly attributs. En intégrant ces vérifications, Aikido garantit que les bonnes pratiques de codage sécurisé (comme l'implémentation de jetons CSRF et de drapeaux de cookies appropriés) sont appliquées de manière cohérente à l'ensemble de votre projet.
5. Injection NoSQL
Tout comme les bases de données SQL traditionnelles souffrent d'injection SQL, les applications JavaScript modernes utilisant des bases de données NoSQL (comme MongoDB, CouchDB, etc.) peuvent être vulnérables à l'injection NoSQL. L'injection NoSQL se produit lorsqu'un attaquant manipule des entrées utilisées dans les requêtes NoSQL, lui permettant de modifier les requêtes, de contourner l'authentification ou de récupérer des données non autorisées. Étant donné que les requêtes NoSQL utilisent souvent des objets JSON ou de requête, la syntaxe est différente de celle du SQL – mais le concept d'injection de paramètres de manière inattendue s'applique toujours.
Exemple concret : Considérez une application Node.js utilisant MongoDB pour l'authentification des utilisateurs, avec un code comme :
// insecure pseudo-codeUsers.findOne({ username: inputUser, password: inputPass })
Cela semble correct à première vue, mais les requêtes MongoDB acceptent des objets et des opérateurs spéciaux. Un attaquant pourrait soumettre une charge utile JSON pour inputPass tels que { "$ne": null }. La requête devient {username: "victim", password: { $ne: null } }, ce qui dans Mongo signifie « trouver un utilisateur avec le nom d'utilisateur 'victim' et un mot de passe qui n'est pas nul » – contournant essentiellement la vérification du mot de passe car $ne: null est toujours vraie pour un champ de mot de passe réel. Ce type de injection d'opérateurs NoSQL est une technique connue pour contourner les formulaires de connexion. La Web Security Academy de PortSwigger documente comment l'injection NoSQL peut « permettre à un attaquant de contourner l'authentification, d'extraire ou de modifier des données, ou même d'exécuter du code sur le serveur » dans certains cas.
Au-delà du contournement de l'authentification, l'injection NoSQL peut être utilisée pour extraire des données. Par exemple, en injectant $regex ou d'autres opérateurs, les attaquants pourraient énumérer les enregistrements d'utilisateurs ou vider les bases de données si l'application n'est pas prudente.
Atténuation :
- Assainissement des entrées : Ne transmettez pas directement les données contrôlées par l'utilisateur aux requêtes de base de données. Assainissez les entrées – par exemple, si vous attendez un nom d'utilisateur de type chaîne de caractères, assurez-vous que c'est bien une chaîne et qu'elle ne contient pas
$ou d'autres caractères spéciaux. Certains ORM ou bibliothèques de pilotes intègrent des vérifications ou des modes pour prévenir l'injection d'opérateurs (par exemple, Mongoose peut désactiver$clés préfixées par défaut). - Utiliser des requêtes paramétrées / ORM : L'utilisation d'un ORM ou d'un constructeur de requêtes peut réduire l'exposition directe aux requêtes brutes. Assurez-vous d'utiliser toutes les fonctionnalités de paramétrisation disponibles.
- Logique d'authentification et de requête : Ne vous fiez pas à une seule condition pour les opérations sensibles. Pour la connexion, préférez un flux de travail qui vérifie indépendamment le mot de passe (après avoir récupéré l'utilisateur par son nom d'utilisateur) plutôt qu'une seule grande requête qui pourrait être manipulée.
- Journalisation et Surveillance : Les tentatives d'injection NoSQL laissent souvent des traces (par exemple, des schémas de requête inhabituels ou des erreurs). Enregistrez les tentatives de connexion échouées et les paramètres de requête inattendus ; cela pourrait aider à détecter une attaque en cours.
L'analyse statique Aikidopermet de détecter les modèles risqués tels que l'utilisation de
findOne()
ou des requêtes similaires avec des entrées utilisateur non vérifiées. Par exemple, Aikido pourrait signaler s'il détecte $ ou des caractères regex concaténés dans une chaîne de requête, ou l'utilisation de Users.findOne({ ... user input ... }) sans désinfection. De plus, analyse dynamique Aikido analyse dynamique si vous l'utilisez contre une instance de développement en cours d'exécution) peut inclure des tests spécifiques pour l'injection NoSQL, de manière similaire à DAST test pour SQLi. En tirant parti de ces outils, les développeurs reçoivent un avertissement précoce : « Attention, cette fonction de connexion pourrait être vulnérable à une injection NoSQL. » En corrigeant le problème rapidement, vous évitez un contournement de l'authentification potentiellement désastreux en production.
6. Déni de service par expression régulière (ReDoS)
Le déni de service par expression régulière (ReDoS) est une vulnérabilité où un attaquant fournit une entrée spécialement conçue à une regex (expression régulière) qui prend un temps d'évaluation exceptionnellement long, monopolisant le CPU et provoquant effectivement un déni de service. Le moteur d'expressions régulières de JavaScript (comme beaucoup d'autres) peut présenter retour arrière catastrophique sur certains motifs. Ceci est particulièrement pertinent pour Node.js, où un seul thread gère de nombreux clients – une regex bloquée peut paralyser toute la boucle d'événements. Des vulnérabilités ReDoS ont été découvertes dans divers packages et frameworks npm. Par exemple, une faille de faible gravité mais notable a été découverte dans le compilateur de templates de Vue.js 2 (CVE-2024-9506) : une regex mal écrite pour l'analyse HTML pourrait être exploitée par un <textarea> ou <script> balise vers « causer des retards significatifs dans l'analyse des modèles ». De même, le populaire path-to-regexp bibliothèque (utilisée dans le routage Express) a eu un problème ReDoS (CVE-2024-52798), et d'innombrables bibliothèques de validation (pour les URL, les e-mails, etc.) ont eu des CVE ReDoS au fil des ans.
Exemple concret : Imaginez un serveur Node.js qui utilise une regex pour valider les adresses e-mail lors de l'inscription d'un utilisateur. Un modèle de regex naïf (par exemple, quelque chose comme /(.+)@(.+)\.(.+)/) pourrait effectuer un retour arrière catastrophique sur une chaîne d'une certaine longueur et composition. Les attaquants pourraient envoyer une chaîne d'e-mail extrêmement longue comme "aaaa....aaaa!" (avec certains motifs) qui fait que la regex s'exécute pendant plusieurs secondes ou plus, période durant laquelle le serveur pourrait ne pas traiter d'autres requêtes. Dans un cas, une ReDoS dans la validator.js la validation d'URL de la bibliothèque a été découverte – une entrée d'URL forgée de quelques dizaines de kilo-octets a bloqué le processus. Si un attaquant automatisait l'envoi de telles entrées en masse, il pourrait effectivement mettre le service hors service. La fondation OWASP note que la plupart des moteurs de regex sont susceptibles à ce genre de cas extrêmes.
Atténuation :
- Évitez les Regex Complexes pour les Entrées Non Fiables : Simplifiez vos motifs de regex ou utilisez des approches sans retour arrière. Si possible, utilisez des bibliothèques intégrées ou des algorithmes éprouvés pour les tâches courantes (par exemple, utilisez l'analyseur d'URL intégré de Node au lieu d'une regex complexe pour les URL).
- Utiliser des délais d'attente : Pour les cas critiques, vous pouvez utiliser une bibliothèque d'expressions régulières qui prend en charge les délais d'attente ou le sandboxing. Dans Node, le
RegExples opérations sont synchrones, mais vous pourriez exécuter le travail de regex dans un thread de travail séparé si nécessaire pour éviter de bloquer la boucle principale. - Limiter la longueur des entrées : Souvent, ReDoS repose sur des chaînes d'entrée très longues. En imposant des limites de longueur raisonnables sur les entrées (par exemple, aucune adresse e-mail ne devrait dépasser 254 caractères selon la RFC), vous réduisez la faisabilité des attaques ReDoS.
- Examiner et tester les motifs : Il existe des outils capables d'analyser les expressions régulières pour détecter un potentiel de backtracking catastrophique. Intégrez-les dans la code review pour tout motif complexe. Rédigez des cas de test avec des entrées pathologiques pour voir comment vos expressions régulières se comportent sous contrainte.
L'analyse des dépendances excelle ici – Aikido suit les CVE et les faiblesses connues dans vos packages npm. Si vous utilisez un package avec un ReDoS connu (par exemple, une version vulnérable d'un analyseur de date ou d'un validateur d'URL), Aikido vous alertera pour que vous mettiez à jour vers une version corrigée. Pour les motifs regex personnalisés dans votre code, le SAST d'Aikido peut repérer les littéraux regex codés en dur ou new RegExp() l'utilisation et appliquer des contrôles heuristiques (par exemple, signaler les motifs avec des quantificateurs excessifs ou des groupes imbriqués). Il ne peut pas détecter toutes les regex malveillantes, mais combiné à la base de connaissances d'Aikido, il peut avertir « Cette regex semble suspectement exponentielle. » De plus, les outils de test d'Aikido peuvent simuler des attaques par fuzzing ; si une charge utile simple provoque des problèmes de performance, vous en seriez informé lors des tests plutôt que par un pager à 2 heures du matin.
7. Traversal de répertoire et exposition de fichiers
Les vulnérabilités de traversée de répertoire (ou de chemin) permettent aux attaquants d'accéder à des fichiers sur le serveur qui étaient censés être inaccessibles, en manipulant les chemins de fichiers. Dans Node.js, cela se produit souvent avec des bibliothèques ou du code qui servent des fichiers statiques, gèrent les téléchargements de fichiers ou traitent des archives zip. Si l'entrée utilisateur est concaténée dans des chemins de fichiers sans une désinfection appropriée, un attaquant peut utiliser des séquences comme ../ pour sortir du répertoire prévu. Par exemple, une vulnérabilité dans le node-static package (un simple serveur de fichiers statiques) a été découverte où une vérification incorrecte dans le servePath fonction permettait à un attaquant de demander une URL avec .. et accéder à des fichiers arbitraires (CVE-2023-26111). Une preuve de concept a montré qu'un attaquant pouvait récupérer des fichiers sensibles tels que /root/.ssh/id_rsa en encodant ../../../../../ dans l'URL.
Exemple concret : Un scénario courant est une application Express utilisant express.static() ou une route de service de fichiers personnalisée. Supposons que vous ayez :
app.get('/download', (req, res) => { const file = req.query.file; res.sendFile(__dirname + '/uploads/' + file);});
Si l'on n'y prend pas garde, un attaquant peut appeler /download?file=../../etc/passwd et récupérer des fichiers système. Il y a eu des cas où des applications ont exposé par inadvertance des clés ou des fichiers de configuration de cette manière. Même lors de l'utilisation de bibliothèques, des bugs ont été signalés : d'anciennes versions du middleware statique d'Express présentaient des problèmes connus de traversée de répertoire dans des cas limites (comme des URL avec des points encodés). La gestion des chemins de base de Node sur Windows présentait également une particularité de traversée (CVE-2025-27210) impliquant des noms de périphériques qui pouvaient être exploités. Au-delà de la lecture de fichiers, l'écriture de fichiers est un autre angle d'attaque (par exemple, les attaques « Zip Slip » où l'extraction d'une archive zip écrit des fichiers en dehors du dossier prévu).
Atténuation :
- Normalisez et validez les chemins : Utilisez
path.normalize()etpath.join()pour résoudre tout..séquences, puis assurez-vous que le chemin résolu se trouve dans le répertoire autorisé. Par exemple, après résolution, rejetez la requête si le fichier est en dehors de votre/uploadsdossier. - Évitez les chemins directement contrôlés par l'utilisateur : Dans la mesure du possible, n'utilisez pas directement les entrées utilisateur comme noms de fichiers. Mappez les entrées utilisateur à des chemins de fichiers prédéfinis. Par exemple, si les utilisateurs ne doivent télécharger que leurs propres fichiers, utilisez un identifiant et recherchez le nom de fichier côté serveur plutôt que de faire confiance à un paramètre de nom de fichier.
- Moindre privilège : Exécutez vos processus Node.js avec des privilèges minimaux. Si l'application n'a aucune raison d'accéder à des répertoires spécifiques, envisagez des restrictions au niveau du système d'exploitation ou la conteneurisation pour limiter les dégâts qu'une traversée de répertoires pourrait causer.
- Maintenez les bibliothèques à jour : Si vous utilisez des bibliothèques de service de fichiers ou de décompression, maintenez leurs correctifs de sécurité à jour. La
node-staticla vulnérabilité mentionnée ci-dessus n'avait « pas de correctif » dans l'ancien package, ce qui pourrait signifier l'utilisation d'une bibliothèque alternative ou l'ajout de votre propre correctif.
Le scanning d'Aikido peut détecter les schémas courants de parcours de répertoire dans le code. Par exemple, l'utilisation de sendFile ou readFile avec req.query ou req.params est un signal d'alarme que nos règles SAST peuvent mettre en évidence. Aikido recoupe également les vulnérabilités connues – si votre projet dépend d'une version de envoyer ou node-static avec une CVE pour la traversée de chemin, il vous invitera à mettre à jour. Pour les équipes DevSecOps, la force d'Aikido réside dans la combinaison de ces signaux : imaginez qu'il signale votre extrait de code de service de fichiers comme risqué et note que vous utilisez une bibliothèque obsolète pour cela – cette information peut entraîner une correction rapide (nettoyer l'entrée et mettre à jour la version de la bibliothèque). Essentiellement, Aikido agit comme un réviseur de sécurité supplémentaire, passant au crible votre logique d'accès aux fichiers afin que les attaquants ne puissent pas passer au crible votre système de fichiers.
8. Dépendances vulnérables et obsolètes
Les applications JavaScript modernes incluent souvent des dizaines, voire des centaines de paquets npm. Chacune de ces dépendances (et leurs sous-dépendances) pourrait abriter des vulnérabilités connues. L'utilisation de bibliothèques obsolètes est si courante qu'elle constitue sa propre catégorie de risque : des versions non sécurisées de frameworks frontend, de modules Node ou de bibliothèques utilitaires peuvent exposer votre application à des attaques même si votre propre code est correct. L'étude 2024 de Claranet a révélé 1 032 instances de bibliothèques JavaScript obsolètes dans 500 applications, notant que « l'utilisation de JavaScript obsolète peut entraîner des attaques XSS, des attaques par déni de service et la divulgation d'informations sensibles ». En d'autres termes, les CVE connues dans les bibliothèques populaires se traduisent directement par des risques pour votre application si vous ne les avez pas mises à jour.
Exemples concrets :
- Lodash: Bibliothèque utilitaire extrêmement populaire. Plusieurs CVE (comme discuté précédemment) ont affecté Lodash – des failles de pollution de prototype (CVE-2018-16487, CVE-2019-10744, CVE-2020-8203) et même un problème de déni de service par expression régulière dans
_.escapeRegExp. Les applications bloquées sur d'anciennes versions de Lodash ont hérité de ces vulnérabilités. - jQuery : Once ubiquitous on the frontend. jQuery <3.5.0 had that XSS vulnerability where injecting
<option>les balises pouvaient exécuter des scripts. Si votre frontend utilise encore, par exemple, jQuery 2.1 ou 3.4, vous transportez des failles XSS connues que les attaquants exploitent activement. - Express et autres : Le framework Express lui-même a eu quelques CVE (redirections ouvertes, un déni de service via des requêtes malformées, etc.). Des packages plus petits comme
moment(bibliothèque de dates) présentait une vulnérabilité de traversée de chemin dans certaines utilisations (CVE-2022-24785),markdown-itprésentait une faille XSS, et ainsi de suite. Même le cœur de Node a eu des vulnérabilités nécessitant des correctifs (comme les problèmes de HTTP request smuggling et de path traversal en 2022-2025).
L'utilisation de composants vulnérables est l'un des OWASP Top Ten (Sous la catégorie « Utilisation de composants avec des vulnérabilités connues »). C'est essentiellement une préoccupation liée à la chaîne d'approvisionnement : si vous intégrez une bibliothèque, vous intégrez également ses bugs.
Atténuation :
- Analyse des dépendances et mises à jour : Exécutez régulièrement
npm auditou des outils similaires pour obtenir une liste des vulnérabilités connues dans vos dépendances. Mettez à niveau les paquets vers des versions corrigées. Utilisez des outils qui vous alertent lorsque de nouvelles vulnérabilités sont découvertes dans les bibliothèques que vous utilisez. - Hygiène des fichiers de verrouillage : Maintenez votre
package-lock.json(ou le fichier de verrouillage Yarn) avec soin. Évitez les problèmes de dépendances imbriquées non résolues en utilisantnpm audit fixle cas échéant. Si une sous-dépendance est vulnérable et ne se met pas à jour, envisagez des "overrides" ou de contacter les mainteneurs. - Dépendances minimales : N'incluez pas de packages dont vous n'avez pas besoin. Chaque dépendance supplémentaire est une faille potentielle de plus. Par exemple, si vous n'avez besoin que d'une petite fonction, il pourrait être plus sûr de l'implémenter que d'intégrer une bibliothèque de 30 fonctions que vous devrez approuver et surveiller.
- Surveiller les avis de sécurité : Restez informé des avis de sécurité dans l'écosystème Node/JS. Abonnez-vous aux listes de diffusion de sécurité Node ou aux alertes Dependabot de GitHub pour vos dépôts.
C'est là que analyse des dépendances les correctifs basés sur l'IAAikido prennent tout leur sens. Aikido analyse Aikido votre arborescence de dépendances par rapport à une base de données de vulnérabilités. Si une nouvelle CVE apparaît, par exemple pour Express ou Lodash, vous recevez une notification et même une suggestion de correction automatique (par exemple, « passer de Lodash 4.17.11 à 4.17.21 pour corriger la CVE-2020-8203 »). Grâce à ses outils conviviaux pour les développeurs, Aikido ne se contente pas de générer un rapport : Aikido également ouvrir une pull request avec la version mise à jour. De plus, la fonctionnalité SafeChain Aikido(un pare-feu intégré à l’application votre gestionnaire de paquets) peut empêcher l'installation de paquets connus pour être malveillants. En intégrant ces outils, votre équipe peut réduire considérablement la fenêtre d'exposition entre le moment où une vulnérabilité de bibliothèque est divulguée et celui où vous la corrigez dans votre application.
9. Packages NPM malveillants et attaques de la chaîne d’approvisionnement
Toutes les attaques ne proviennent pas d'erreurs de codage – certaines proviennent du code que vous thought vous pouviez faire confiance. L'écosystème npm a souffert d'attaques de la chaîne d’approvisionnement où des attaquants subvertissent l'approvisionnement en packages pour insérer du code malveillant. Cela peut se produire par des techniques comme typosquatting (publier un package avec un nom similaire à un package populaire, en espérant que quelqu'un fasse une faute de frappe ou l'installe par erreur), ou en compromettant les mainteneurs de projets légitimes. Un incident tristement célèbre a été le event-stream attaque en 2018 : un attaquant a convaincu le mainteneur de event-stream (un paquet largement utilisé) de céder le contrôle, puis a publié une nouvelle version qui incluait une dépendance cachée (flatmap-stream) contenant un malware. En quelques mois, cette mise à jour malveillante a été téléchargée des millions de fois, et elle a spécifiquement ciblé une application de portefeuille Bitcoin (Copay) pour voler des clés de cryptomonnaie.
D'autres exemples incluent des paquets comme ua-parser-js, node-ipc, et event-source-polyfill qui ont été soit détournés par des attaquants, soit sabotés par leurs propres développeurs pour livrer des charges utiles indésirables (comme des logiciels espions, des mineurs de cryptomonnaie ou des scripts destructeurs). En 2021, des chercheurs en sécurité ont démontré des attaques de « dependency confusion » (confusion de dépendances) – où si une entreprise utilise un nom de paquet interne et qu'un attaquant publie un paquet portant le même nom sur npm, les outils de build pourraient récupérer la version de l'attaquant. Ces scénarios sont particulièrement dangereux car ils peuvent donner aux attaquants l'exécution de code à distance pendant votre build ou en production, sans exploiter aucune vulnérabilité traditionnelle.
Atténuation :
- Vérifier l'authenticité des paquets : Utilisez les hachages d'intégrité des paquets (npm utilise automatiquement
le fichier package-lockavec des hachages sha512 pour les paquets – gardez ce lockfile commité). Envisagez d'activer la 2FA sur les comptes npm et préférez les paquets provenant de sources fiables. - Sécurisez les dépendances internes : Si vous utilisez des packages privés, assurez-vous que votre registre ou votre processus de build ne récupère pas accidentellement des éléments du registre public. Nommez les packages internes ou utilisez des registres à portée.
- Surveillez les scripts d'installation : Méfiez-vous des packages qui contiennent des scripts d'installation/post-installation. Auditez ce que ces scripts exécutent (certains packages malveillants les utilisent pour lancer des commandes nuisibles lors de l'installation).
- Utilisez les outils de sécurité : Exploitez l'audit de npm et d'autres outils pour identifier les anomalies. Par exemple, si un package largement utilisé publie soudainement une nouvelle version mineure après une longue période d'inactivité, traitez-le avec prudence (comme ce fut le cas avec la version 3.3.6 d'event-stream).
- principe du moindre privilège : Lorsque vous exécutez des builds ou de la CI, faites-le dans des environnements sandboxés. Pour la production, envisagez des mécanismes comme celui de Node.js
--experimental-policypour contrôler quels modules peuventrequirequoi, ou la conteneurisation pour limiter les dommages.
Aikido protéger votre chaîne logistique logicielle. Aikido , par exemple, peut analyser les métadonnées des paquets et même leur contenu à la recherche d'indicateurs malveillants. Il peut bloquer l'installation de paquets connus pour être compromis ou qui présentent un comportement suspect (comme des scripts post-installation obscurcis). renseignement sur les menaces Aikidosurveille les logiciels malveillants dans les paquets open source. Ainsi, si demain une bibliothèque populaire est piratée, Aikido vous avertir ou empêcher les mises à jour vers la version corrompue. De plus, SAST Aikido SAST détecter l'utilisation d'opérations sensibles dans les dépendances (par exemple, si une dépendance commence soudainement à exécuter des commandes shell ou à accéder au réseau de manière inattendue). En intégrant ces outils dans votre pipeline, vous ajoutez une solide couche de défense contre la prochaine attaque de type « event-stream », ce qui revient essentiellement à disposer d'un vérificateur de code automatisé pour le code tiers.
10. Secrets codés en dur et identifiants exposés
Le codage en dur de secrets (clés API, jetons, mots de passe) dans votre code JavaScript ou votre configuration est une pratique risquée qui reste malheureusement courante. Dans le code frontend, tout secret (par exemple, une clé API pour un service tiers) est visible par l'utilisateur final et doit être traité comme public – mais les développeurs l'oublient parfois et laissent des jetons sensibles dans le bundle JS. Dans le code backend Node.js ou les fichiers de configuration, les secrets peuvent être committés dans Git et se retrouver dans le contrôle de version ou dans le package déployé. L'exposition des secrets peut entraîner un accès non autorisé, une prise de contrôle de compte ou des factures coûteuses (par exemple, si un attaquant trouve une clé API d'un fournisseur cloud, il peut lancer des ressources ou vider vos bases de données).
L'ampleur de ce problème est mise en évidence par la recherche : rien qu'en 2024, près de 23,8 millions de nouveaux secrets codés en dur ont été détectés dans les commits publics de GitHub, soit une augmentation de 25 % par rapport à l'année précédente. Des violations de grande envergure se sont produites en raison de fuites d'identifiants – par exemple, une fuite d'identifiants du New York Times et une autre chez Sisense ont été attribuées à la prolifération de secrets. Même dans les images Docker, des milliers de clés API ont été trouvées intégrées par inadvertance. Le point à retenir : l'exposition des secrets est monnaie courante et souvent le moyen le plus facile pour les attaquants de s'introduire sans exploiter une faille logicielle.
Exemple concret : En 2019, un développeur a accidentellement poussé une chaîne de connexion MongoDB (avec identifiants) vers un dépôt GitHub public. En quelques heures, des attaquants scannant GitHub l'ont trouvée, ont accédé à la base de données et ont retenu les données en otage. Dans un autre cas, des développeurs d'applications mobiles ont laissé une clé privée Firebase dans le JavaScript de l'application – des attaquants l'ont extraite et ont accédé aux données utilisateur sur Firebase. Ces exemples montrent que, que ce soit dans un .js fichier, un .env fichier commis par erreur, ou n'importe où dans votre base de code, les secrets sont une cible facile pour les attaquants s'ils sont exposés.
Atténuation :
- Ne jamais coder en dur les secrets : Utilisez des variables d'environnement ou un service de gestion des secrets. Votre application Node.js peut lire depuis
process.envà l'exécution, plutôt que d'avoir le secret dans le code source. Pour les besoins du frontend, envisagez de proxifier les requêtes via votre backend afin que le secret ne soit pas exposé, ou utilisez des flux OAuth qui ne nécessitent pas l'intégration de secrets. - Ignorer Git et le scan : Ne commettez pas
.envfichiers ou d'autres fichiers contenant des secrets. Utilisez.gitignorepour les exclure. De plus, utilisez des outils de scan de secrets (GitHub dispose d'un scanner de secrets intégré pour les dépôts publics, et des outils tiers peuvent scanner les commits) pour détecter tout secret qui s'y glisserait. - Faites pivoter les clés : En cas de suspicion de fuite d'un secret, faites-le pivoter immédiatement. Ayez un plan de rotation des clés et utilisez des identifiants distincts pour différents environnements (afin qu'une fuite en dev ne compromette pas la prod, par exemple).
- Coffres-forts et gestion de la configuration : Utilisez un coffre-fort de secrets approprié ou un gestionnaire de secrets cloud pour stocker et récupérer les secrets à l'exécution, plutôt que de les stocker dans des fichiers de configuration.
Aikido détection de secrets qui analysent en permanence votre code et vos configurations à la recherche de modèles d'identifiants. Par exemple, si quelqu'un valide accidentellement une clé d'accès AWS ou un jeton API, Aikido le Aikido (même pendant une demande d'extraction) avec une alerte hautement prioritaire. Il reconnaît les modèles et peut également utiliser le contexte (par exemple, une chaîne hexadécimale de 40 caractères dans un fichier de configuration peut être signalée comme une clé API potentielle). De plus, la plateforme Aikidopeut s'intégrer au contrôle de version pour empêcher les secrets d'atteindre la production, en les interceptant dans le pipeline CI. Cela revient à avoir un gardien qui vérifie « Êtes-vous sûr de vouloir valider cette clé ? ». Si un secret est détecté, Aikido aider à évaluer son impact en identifiant les endroits où il pourrait s'être propagé et même en suggérant des mesures correctives (comme les clés à remplacer). Grâce à cet outil, les développeurs peuvent valider les dépôts en toute confiance, sans craindre de publier par inadvertance les clés du royaume.
Conclusion
La force de JavaScript – son omniprésence et sa flexibilité, du navigateur au backend – est précisément ce qui rend sa sécurisation une tâche si critique. Nous avons vu à quel point une simple négligence (une sortie non assainie, un package obsolète, une clé API divulguée) peut compromettre la sécurité d'une application. La bonne nouvelle est que la sensibilisation et les bonnes pratiques sont très efficaces : en comprenant ces principales vulnérabilités, les développeurs peuvent éviter les erreurs courantes comme l'évaluation de données non fiables ou laisser une porte ouverte via ../ dans un chemin. Adopter une approche axée sur la sécurité signifie valider les entrées, encoder les sorties, mettre à jour les dépendances et ne jamais supposer que « personne ne remarquera mon erreur » – car si vous ne la détectez pas, un attaquant finira par le faire.
Intégrez la sécurité dans votre processus de développement. Adoptez des habitudes de codage sécurisées (consultez les fiches pratiques OWASP, utilisez des linters et des vérificateurs de type pour détecter les problèmes à un stade précoce). Et tirez parti des outils de sécurité intégrés qui vous accompagnent, de analyse statique du code l'audit des dépendances et analyse statique du code la recherche de secrets. Des solutions telles que Aikido vous permettent d'intégrer ces pratiques dans votre pipeline CI/CD, afin que chaque commit et chaque build soient automatiquement vérifiés pour détecter les vulnérabilités. En détectant les problèmes tôt et souvent, vous réduisez les risques sans ralentir. Le monde du JavaScript évolue rapidement, mais avec les bonnes mesures de protection en place, vous pouvez innover tout aussi rapidement sans exposer votre application. Livrez en toute confiance et en toute sécurité : vos utilisateurs et votre DevSecOps vous en seront reconnaissants !
Continuer la lecture :
Top 9 Docker sécurité des conteneurs
Top 7 Vulnérabilités Cloud
Top 10 Vulnérabilités de sécurité des applications web que chaque équipe devrait connaître
Top 9 sécurité Kubernetes et erreurs sécurité Kubernetes
Principales vulnérabilités de sécurité du code dans les applications modernes
Top 10 Vulnérabilités de sécurité Python que les développeurs devraient éviter Top 9 sécurité de la chaîne d’approvisionnement logicielle

