Skip to main content

Des plugins pour intégrer la sécurité et l’observabilité des applications Node.js à votre IDE

Écrit par
blog feature javascript review

23 août 2021

0 minutes de lecture

En tant que développeurs, nous passons beaucoup de temps dans nos IDE à écrire du code, à le refactoriser, à ajouter des tests, à corriger des bugs et bien plus encore. Ces dernières années, les IDE sont devenus des outils puissants qui nous aident dans toutes sortes de tâches, de l’interaction avec les requêtes HTTP à l’amélioration générale de notre productivité. On peut donc se demander : et si nous pouvions aussi prévenir les problèmes de sécurité dans notre code avant sa mise en production ? Et si nous pouvions voir, au niveau du code et directement dans l’IDE, ce qui se passe dans nos applications en production ?

C’est là qu’intervient la magie des outils conçus pour les développeurs. Avec le bon plugin pour votre IDE, l’observabilité et la sécurité peuvent être intégrées aux workflows quotidiens des développeurs, là où elles sont le plus efficaces.

Dans cet article, nous allons voir :

  • Comment obtenir une observabilité en temps réel, au niveau du code, de vos structures de données directement dans votre IDE

  • Comment repérer les entrées utilisateur malveillantes dans une application Node.js en production

  • Comment détecter et corriger les problèmes de sécurité dans votre code et vos dépendances open source

Comment obtenir une observabilité des applications en temps réel dans votre IDE

Voici ce dont vous avez besoin pour suivre cet article :

  1. IntelliJ IDEA (la prise en charge de Visual Studio Code par Lightrun sera bientôt disponible : inscrivez-vous à la bêta ici pour en profiter en avant-première !)

  2. Un compte Lightrun, le plugin IntelliJ de Lightrun et le Node.js Agent, qui est encore en version bêta

Une fois le plugin IntelliJ IDEA installé, cliquez sur le bouton Register pour suivre une procédure d’inscription simple dans votre navigateur :

IDE en thème sombre affichant du code JavaScript, un panneau d’accueil Lightrun avec les boutons « Connexion » et « Inscription », ainsi qu’un panneau d’analyse de sécurité Snyk

Ensuite, nous devons installer et configurer l’agent Node.js de Lightrun pour l’application Node.js. Les instructions s’afficheront pendant l’inscription. Si vous les avez manquées, les voici de nouveau :

  1. Installez l’agent Lightrun dans le dossier de notre projet en exécutant : npm install lightrun

  2. Initialisez l’agent Lightrun au début du code de notre application Node.js, dans le fichier d’entrée app.js, comme suit (les valeurs <YOUR-COMPANY-NAME> et <YOUR-COMPANY-SECRET> s’affichent à l’écran pendant l’inscription) :

    require('lightrun').start({ company: '', apiEndpoint: 'app.lightrun.com', lightrunSecret: '', caPath: '',});

Je ne ferais pas mon travail correctement sans évoquer le problème des secrets dans le code. La première chose à faire une fois arrivé à cette étape est donc de modifier la ligne de code pour que lightrunSecret soit défini ainsi :

require('lightrun').start({
    company: '<YOUR-COMPANY-NAME>',
    apiEndpoint: 'app.lightrun.com',
    lightrunSecret: '<YOUR-COMPANY-SECRET>',
    caPath: '',
});

Ensuite, lorsque vous démarrez l’application en local, pensez à rendre cette variable d’environnement disponible au préalable. Si vous lancez l’application depuis la ligne de commande, vous pouvez procéder ainsi :

lightrunSecret: process.env.LIGHTRUN_API_KEY

Remarque : Il suffit d’exécuter la commande export une seule fois. Elle restera disponible dans votre session de terminal tant que vous utilisez la même.

Une fois l’application démarrée, vous remarquerez dans la barre latérale droite que le plugin Lightrun est correctement configuré et connecté. Le nom de votre machine l’indique (la mienne s’appelle « Lirans-MBP ») :

export LIGHTRUN_API_KEY=<YOUR-COMPANY-SECRET>
npm run start

Comment repérer les entrées utilisateur malveillantes dans une application Node.js en production

L’application Node.js que nous allons tester est Goof, l’application TODO de Snyk : une application de prise de notes et de gestion de tâches de bout en bout, conçue avec JavaScript et Node.js.

Vous pouvez en récupérer une copie en clonant le projet GitHub, puis suivre les instructions habituelles d’installation des dépendances pour les projets npm. Notez qu’elle doit également se connecter à une base de données MongoDB au démarrage.

Une fois l’application démarrée, vous devriez voir quelque chose de semblable à la capture d’écran ci-dessous. Elle possède une fonctionnalité intéressante : si je lui envoie une tâche telle que Get my app secured in 15 minutes, elle utilise le package npm open source humanize-ms pour transformer le texte 15 minutes en une chaîne au format [15m]. Le package humanize-ms totalise environ 4 500 000 téléchargements par semaine : il semble donc être un bon choix.

Fenêtre de navigateur affichant une application « Goof TODO » avec des tâches liées à la sécurité des applications, à un plug-in IDE et à l’observabilité et la sécurité.

Si vous êtes attentif à la sécurité et avez déjà développé des applications backend, vous avez probablement veillé à ce que les entrées respectent certaines validations et un schéma attendu.

Pourtant, cette application est maintenant en production et, même si je ne sais pas quel type d’entrées utilisateur elle reçoit, je ne veux pas casser ses fonctionnalités. Je voudrais toutefois pouvoir repérer les entrées utilisateur potentiellement dangereuses qu’elle pourrait recevoir. C’est là que Lightrun fait la différence !

Je veux recevoir des alertes si quelqu’un envoie une entrée utilisateur de plus de 10 000 caractères. Pour cela, je vais ajouter un log Lightrun conditionnel dans IntelliJ, directement sur la ligne de code qui analyse le texte fourni par l’utilisateur. Voici à quoi cela ressemble :

Éditeur de code affichant le menu Lightrun avec des options pour les journaux, les points d’arrêt virtuels, les métriques, les instantanés, les paramètres et la déconnexion

Pour ce faire, faites un clic droit sur la ligne de code, choisissez le type d’annotation Log, puis configurez la règle de journalisation comme suit : item.length>10000

Éditeur de code affichant une boîte de dialogue « Create Log » configurée pour la ligne 162 de index.js, avec la condition item.length > 10000.

Cela crée en quelque sorte une alerte dans mon application Node.js en cours d’exécution : chaque requête qui atteint ce chemin de code et satisfait la condition, avec une entrée de plus de 10 000 caractères, déclenche l’alerte.

Une fois l’action ajoutée, une petite annotation apparaît au-dessus de la ligne de code, avec le nom de la personne qui l’a ajoutée. C’est un bon moyen d’attirer l’attention et de fournir des informations utiles aux développeurs qui seront chargés de la dette technique et du refactoring à l’avenir :

Éditeur de code en thème sombre affichant du JavaScript qui analyse une saisie utilisateur et enregistre une nouvelle tâche avec son contenu et sa date de mise à jour

Ajouter une alerte depuis l’IDE, c’est bien. Mais savez-vous ce qui est encore mieux ? Pouvoir afficher ces alertes directement dans la console de l’IDE, sans ouvrir une nouvelle page Web pour consulter les logs.

Pour que cela fonctionne, accédez à la barre latérale droite du plugin Lightrun, puis cliquez sur l’icône la plus à droite de l’entrée de l’agent, celle intitulée PIPE. Cliquez ensuite sur le bouton Both. Les logs d’alerte seront alors envoyés à la fois à l’application SaaS Lightrun et directement à la console Lightrun de mon IDE. Génial !

Interface d’application sombre affichant l’agent de production Lirans-MBP, la ligne 162 de index.js et un menu ouvert proposant les options App, Plugin et Both.

Maintenant que l’alerte est configurée, testons l’envoi de charges utiles volumineuses. Pour cela, je vais utiliser quelques outils pratiques en ligne de commande :

  1. Une configuration de shell Oh My Zsh (qui n’aime pas une invite de commande élégante ?)

  2. L’outil HTTPie pour envoyer la requête HTTP qui ajoute une tâche

  3. L’outil Unix seq pour répéter facilement un caractère un certain nombre de fois

Avec ces outils, je vais envoyer la charge utile à l’aide de la commande suivante :

echo 'content=Buy milk in 'seq -s "" -f "5" 60000 'minutes' | http --form http://localhost:3001/create -v

Cela crée le texte de tâche Buy milk in 500000... minutes, où le chiffre 5 est suivi de 60 000 zéros supplémentaires : une chaîne plutôt longue.

Voici le résultat dans l’interface de l’application :

Fenêtre de navigateur affichant une application « Goof TODO » avec des tâches : acheter du lait, sécuriser une application, télécharger un plugin pour IDE, et assurer l’observabilité et la sécurité.

Comme vous pouvez le constater, l’application n’a pas planté, pas plus que la base de données MongoDB. L’effet secondaire semble se limiter au fait que le package npm humanize-ms analyse simplement cette durée et la convertit en Infinity. En somme, c’est logique et ce n’est pas un problème à proprement parler. Enfin, en apparence.

Vous vous souvenez que nous avons configuré une alerte dans l’IDE ?

Voyons ce que cela donne…

Vous voyez la ligne en surbrillance dans la fenêtre de la console Lightrun ? Nous recevons directement dans l’IDE des alertes correspondant à une condition de journalisation, déclenchées par une requête HTTP envoyée à une application en production. C’est très utile (vraiment très utile, même !).

Éditeur de code sombre affichant du JavaScript, avec un panneau Lightrun et une console signalant une entrée utilisateur potentiellement longue et dangereuse.

Mais pourquoi tout ce battage autour de cette alerte ? Voyons cela…

Comment détecter et corriger les problèmes de sécurité dans votre code et vos dépendances open source

Il s’avère que cette version du package npm humanize-ms présente des vulnérabilités de sécurité indirectes. Ses 4 500 000 téléchargements hebdomadaires étaient trompeurs ! La vulnérabilité de sécurité de ce package pourrait avoir des conséquences très graves pour toute application Web Node.js.

Comment le sais-je ? J’ai installé le plugin IntelliJ de Snyk et lui ai demandé d’analyser mon projet : il a détecté cette vulnérabilité et plusieurs autres. Voyons comment lancer une analyse et évaluer la gravité de cette vulnérabilité à l’aide de l’alerte de Lightrun concernant une charge utile volumineuse.

Une fois le plugin IntelliJ de Snyk installé et authentifié (consultez ce guide d’installation du plugin, étape par étape), cliquez sur le bouton vert Play dans la fenêtre du plugin Snyk pour lancer une analyse de sécurité.

L’analyse recherche les problèmes de sécurité potentiels suivants :

  1. Les vulnérabilités de sécurité dans vos bibliothèques open source tierces, comme les packages npm que vous importez dans votre code. Si vous analysez des projets écrits dans d’autres langages de programmation, comme Java, Ruby ou Python, Snyk détecte automatiquement le fichier manifeste des packages et les analyse également.

  2. Les problèmes de sécurité du code dans votre propre code. Les langages actuellement pris en charge sont JavaScript, TypeScript, Java et Python.

Voici les résultats de l’analyse de sécurité Snyk Open Source pour les packages npm tiers que j’ai ajoutés comme dépendances à ce projet TODO :

Éditeur de code JavaScript affichant une fonction d’enregistrement de tâches, à côté d’un panneau Snyk répertoriant des vulnérabilités de sécurité open source

En parcourant les résultats, vous constaterez que cette application TODO contient un bon nombre de vulnérabilités de sécurité. Il s’agit d’une application volontairement vulnérable, qui nous permet de présenter, de mettre en pratique et d’étudier ces vulnérabilités, ainsi que les façons de les corriger.

Vous vous souvenez de notre package npm humanize-ms, qui analyse et formate les chaînes représentant des durées ? Il introduit apparemment une vulnérabilité de déni de service par expression régulière (ReDOS), car il dépend d’une plage de versions vulnérables du populaire package npm ms :

Éditeur de code à thème sombre affichant les résultats d’analyse des vulnérabilités Snyk, notamment des problèmes de scripts intersites, de pollution de prototype et de déni de service par expression régulière.

Revenons à la charge utile de notre exploit et examinons-la de nouveau :

echo 'content=Buy milk in 'seq -s "" -f "5" 60000 'minutes' | http --form http://localhost:3001/create -v

Comme vous vous en souvenez, cette commande envoyait une très longue chaîne comme tâche, mais ne semblait pas provoquer de déni de service. L’application continuait à traiter les requêtes normalement et l’application Node.js renvoyait une réponse presque immédiatement.

Cependant, les expressions régulières sont… délicates. Si elles sont mal écrites, elles peuvent être vulnérables au retour arrière catastrophique, ce qui signifie essentiellement qu’un traitement dont la durée devrait être linéaire peut prendre un temps superlinéaire.

Pour que ma charge utile d’exploit attaque efficacement cette application, il suffit de remplacer le mot minutes par minutea, puis d’exécuter la commande. Pour comparer l’avant et l’après, regardez cette capture d’écran prise avant l’envoi de la requête : la commande htop montre une activité normale du processeur sur mon ordinateur portable.

Espace de travail d’un développeur affichant du code JavaScript, des processus dans un terminal et un panneau Snyk détaillant une vulnérabilité de déni de service par expression régulière.

Avec une vulnérabilité ReDOS, je m’attends à ce que l’application Node.js mette beaucoup de temps à évaluer l’expression régulière. Comme Node.js fonctionne sur un seul thread, toutes les requêtes suivantes seront bloquées. Le processeur atteindra 100 % et épuisera toutes les ressources disponibles à tenter de calculer l’expression régulière, sans succès.

Envoyons notre charge utile d’exploit ReDOS :

echo 'content=Buy milk in 'seq -s "" -f "5" 60000 'minutea' | http --form http://localhost:3001/create -v

Et voilà ! En haut à droite, le terminal affiche la requête HTTP envoyée, sans réponse immédiate. En bas à gauche, le processus Node.js apparaît en vert en haut du tableau et consomme 98,4 % du processeur :

Espace de travail de développeur en mode sombre affichant du code JavaScript, des processus de terminal, une console remplie de caractères répétés et des détails sur les vulnérabilités Snyk.

L’étape suivante consiste bien sûr à corriger ce problème et les autres problèmes de sécurité. Une fois vos projets importés dans l’application Snyk, ils sont analysés et surveillés en continu en arrière-plan. Snyk crée aussi automatiquement des pull requests dans vos dépôts Git, sur GitHub ou ailleurs, pour mettre à niveau les versions vulnérables de vos projets. Pour en savoir plus, consultez l’article Bien démarrer avec Snyk Open Source.

Sécurité et observabilité pensées pour les développeurs

Les outils conçus pour les développeurs, comme Lightrun et Snyk, leur permettent d’être plus productifs au quotidien en mettant les données à leur disposition, plutôt que de les détourner de leurs workflows.

En intégrant l’observabilité et la sécurité directement dans l’IDE IntelliJ ou dans la ligne de commande, les développeurs peuvent surveiller le trafic en temps réel et détecter puis corriger les problèmes de sécurité avant même qu’ils n’atteignent le serveur d’intégration continue — et à plus forte raison la production.

Pour vous lancer avec ces deux outils, consultez les ressources suivantes :

  1. Premiers pas avec Snyk

  2. Premiers pas avec Lightrun

Lancez-vous dans les compétitions Capture The Flag

Apprenez à résoudre des défis Capture The Flag en regardant à la demande notre atelier virtuel d’initiation.