Comment prévenir les vulnérabilités d’injection de journaux dans les applications JavaScript et Node.js
26 septembre 2024
0 minutes de lectureDans de nombreuses applications d’entreprise classiques, la journalisation systématique répond à de multiples besoins. Elle aide les entreprises à détecter et corriger les erreurs, fournit de précieuses informations analytiques et permet de tester de nouvelles solutions. Toutefois, elle fait aussi de l’injection de journaux l’un des moyens les plus courants pour les pirates de détourner des données ou même d’accéder à des informations sensibles sur les utilisateurs. Les vulnérabilités liées à la journalisation des données par les applications peuvent permettre aux attaquants d’injecter du code malveillant dans les journaux, compromettant ainsi l’intégrité et la confidentialité de votre application.
Dans cet article, vous allez vous intéresser plus particulièrement aux vulnérabilités d’injection de journaux dans Node.js. Vous découvrirez leur fonctionnement et apprendrez des méthodes efficaces pour les prévenir.
Qu’est-ce qu’une vulnérabilité d’injection de journaux ?
Pour journaliser des informations, certaines applications écrivent dans un fichier externe ou s’appuient sur une API externe à laquelle elles envoient leurs journaux. Une injection de journaux se produit lorsqu’un attaquant manipule les données saisies pour injecter du code malveillant dans les journaux de l’application. Ces journaux servent généralement au débogage, à la surveillance et à l’audit.
Lorsqu’une injection de journaux se produit, l’attaquant peut encombrer les journaux ou même exécuter du code dans le contexte de l’application, ce qui entraîne divers risques de sécurité.
Exemple d’application Node.js vulnérable
Prenons l’exemple d’une application Node.js simple qui utilise le framework Web Express pour journaliser les données fournies par les utilisateurs sans validation ni assainissement adéquats. L’extrait de code suivant illustre cette vulnérabilité :
Une fois le serveur démarré et opérationnel en local, vous pouvez envoyer une requête GET avec des outils de test d’API comme Insomnia pour vérifier que tout fonctionne comme prévu. Dans cet exemple, vous souhaitez journaliser le nom d’utilisateur saisi dans un formulaire afin de vérifier le contenu des journaux du serveur. Vous ajoutez les données au format attendu par le serveur et envoyez la requête. Vous obtenez alors une réponse 200 OK et le message « Data logged successfully. » :

Si vous consultez les journaux côté serveur, tout semble être enregistré comme prévu. Comme vous avez ajouté la valeur charlie aux paramètres de données, le journal indique que INFO: charlie a été enregistré sur le serveur :

Une personne malveillante pourrait notamment exploiter la façon dont cette application journalise les données en insérant de fausses entrées via le paramètre data. Dans cet exemple, il lui suffirait d’ajouter du texte à la requête :


Par exemple, une personne malveillante peut ajouter INFO: User deleted pour créer une fausse entrée. Lorsque l’équipe de développement la découvrira, elle risque d’être induite en erreur et de perdre du temps et des ressources à chercher pourquoi l’application supprime ses utilisateurs lorsqu’un utilisateur saisit un nom d’utilisateur, alors qu’un attaquant a simplement ajouté des caractères à un champ de saisie.
Cet exemple est simpliste, mais il vous aide à comprendre ce que sont les injections de journaux en général. D’autres types d’injection peuvent consister à ajouter de fausses entrées d’erreur ou de fausses informations sur les utilisateurs en modifiant simplement le message du journal ou, pire encore, à insérer des injections de commandes qui permettraient aux attaquants de manipuler directement les données internes.
Comment prévenir les vulnérabilités d’injection de journaux dans Node.js
Pour réduire les risques de vulnérabilités d’injection de journaux dans vos applications Node.js, envisagez d’appliquer certaines de ces pratiques courantes :
Assainir les entrées utilisateur
Dans la plupart des cas, les entrées utilisateur doivent être validées et assainies avant d’être journalisées. Cela signifie qu’il faut vérifier soigneusement toutes les données à enregistrer afin d’exclure les caractères susceptibles d’être interprétés comme une autre entrée de journal et/ou de ne conserver que les caractères autorisés dans les journaux.
Dans l’exemple précédent, vous pouvez notamment assainir les journaux à l’aide d’une expression régulière qui filtre les caractères et n’autorise que les lettres, empêchant ainsi l’ajout de caractères spéciaux ou de chiffres dans le journal :

Il faut toutefois garder à l’esprit qu’il peut être difficile de choisir la bonne méthode d’assainissement des données. Dans cet exemple, le nom d’utilisateur d’une personne contenant des chiffres (par ex. 123) sera modifié dans les journaux.
L’assainissement des entrées peut aider à détecter les entrées malveillantes dans les journaux, mais il impose aux développeurs de faire particulièrement attention aux données filtrées et à la manière de les filtrer. Par exemple, une expression régulière mal écrite peut entraîner des vulnérabilités ReDOS qui paralysent les applications Node.js. Utiliser des packages npm tiers comme validator.js est une bonne façon d’éviter de réinventer la roue, mais veillez à maintenir ces dépendances à jour.
Faites attention à ce que vous journalisez
Chaque application est unique. Aucune norme de journalisation ne peut couvrir tous les besoins susceptibles de se présenter pour chaque application. Il est important de déterminer quelles informations vous devez journaliser et pour qui.
Les journaux de niveau DEBUG peuvent aider les développeurs à suivre ce qui se passe dans leur application, à comprendre comment l’utilisateur passe d’un composant à un autre ou comment les informations circulent d’une source à une autre. Les journaux de niveau WARN ou ERROR peuvent aider les équipes d’ingénierie à détecter rapidement les bugs potentiels et à comprendre ce qui provoque le plantage ou le dysfonctionnement de l’application. L’essentiel est de journaliser uniquement les informations nécessaires, sans plus, tout en tenant compte des conséquences d’une compromission de vos journaux par des attaquants.
Comme l’explique cet article de Snyk sur les vulnérabilités liées à la journalisation, l’envoi d’informations sensibles à un service de journalisation externe peut exposer les données aux attaquants. En règle générale, évitez de journaliser des informations sensibles ou confidentielles, comme des mots de passe, des clés API ou des données personnelles. Si vous devez le faire, mettez en place des contrôles d’accès adaptés et envisagez d’utiliser des variables d’environnement (par exemple dans GitHub Actions) ainsi que des systèmes de gestion des clés pour protéger vos données de configuration sensibles.
En plus de réfléchir aux informations que vous journalisez, vous devez aussi vous demander comment vous le faites. La journalisation structurée permet d’organiser les données de manière plus claire, ce qui facilite leur interprétation par les développeurs. Par exemple, dans le cas précédent, au lieu de journaliser directement les données utilisateur sous forme de chaîne, vous pouvez utiliser un objet JSON pour mieux structurer les informations enregistrées :
Plus important encore, structurer les journaux de cette manière peut compliquer leur injection par les attaquants, car l’objet journalisé comporte plusieurs propriétés qu’ils devraient aussi manipuler (c’est-à-dire action ou time). S’ils ne le font pas, leur tentative peut être démasquée :

La journalisation d’un objet JSON présentée ici est un exemple simpliste. Il existe des bibliothèques de journalisation (présentées dans la section suivante) qui offrent la journalisation structurée comme solution de remplacement pratique à l’habituel console.log.
Utilisez une bibliothèque de journalisation plutôt que console.log
De nombreuses bibliothèques de journalisation offrent un meilleur contrôle et une sécurité accrue des sorties que console.log, car elles incluent généralement des fonctionnalités intégrées d’assainissement et de filtrage pour prévenir les attaques par injection de journaux. Elles permettent également aux développeurs de contrôler les journaux affichés dans chaque environnement (test ou production), de choisir où les envoyer (fichier local, base de données et/ou API tierce) et de configurer leur format pour en faciliter le suivi.
Nous recommandons notamment pino, une bibliothèque bien entretenue et globalement fiable, qui ne présente aucune vulnérabilité connue.
Pino est hautement optimisé pour les performances et peut être configuré pour ajouter des horodatages à chaque entrée de journal. Il prend en charge la journalisation structurée ainsi que les niveaux de journalisation standard du système. Cette complexité et cette structure supplémentaires peuvent renforcer la sécurité et réduire le risque de compromission des journaux par des attaquants.
Utilisez l’extension IDE Snyk pour VS Code afin de détecter les vulnérabilités
Snyk propose une extension IDE gratuite pour Visual Studio Code (VS Code) qui peut vous aider à détecter les vulnérabilités d’injection de journaux (entre autres) dans votre code Node.js. Voici comment la configurer :
Dans VS Code, accédez à l’onglet Extensions et recherchez « Snyk » pour trouver l’extension « Snyk Security - Code, Open Source Dependencies, Iac Configurations ». Cliquez sur Installer :

Une fois l’extension installée, Snyk vous demandera d’authentifier votre compte en le connectant à votre IDE. Cliquez sur Connect VS Code with Snyk : une page Web Snyk externe s’ouvre et vous demande l’autorisation de vous connecter. Cliquez ensuite sur Authenticate.
Une fois l’authentification terminée, cliquez sur Scan pour rechercher des vulnérabilités dans votre code. Vous pouvez également configurer l’extension selon vos besoins :

L’extension IDE Snyk analyse automatiquement votre code à la recherche de vulnérabilités d’injection de journaux. De plus, pendant l’analyse, Snyk met en évidence d’autres problèmes de sécurité potentiels dans votre code, notamment les secrets codés en dur ou les vulnérabilités de traversée de chemin, et vous propose des conseils et des recommandations concrètes pour sécuriser votre application.
Démarrez gratuitement avec Snyk
Aucune carte bancaire requise.
Créer un compte avec Bitbucket et découvrir d’autres options
En utilisant Snyk, vous acceptez de respecter nos politiques, notamment nos Conditions d’utilisation et notre Politique de confidentialité.



