Skip to main content

Prévenir les attaques par falsification de requêtes côté serveur dans les applications Node.js

Écrit par

David Ekete

blog feature multithreading

20 février 2024

0 minutes de lecture
How to prevent SSRF Attacks in Node.js

La falsification de requêtes côté serveur (SSRF) est une vulnérabilité courante qui peut apparaître sans qu’on s’en rende compte dans n’importe quelle application Node.js. Elle représente une menace importante, car des attaquants peuvent manipuler un serveur pour qu’il envoie des requêtes imprévues vers des ressources internes comme externes.

Cet article présente les attaques SSRF, leurs risques potentiels et les stratégies pour les prévenir dans les applications Node.js.

Fortement recommandé : Suivez le cours interactif sur la falsification de requêtes côté serveur sur Snyk Learn.

Qu’est-ce que la SSRF ?

Une attaque SSRF se produit lorsqu’un attaquant exploite les requêtes envoyées par le serveur d’une application web en modifiant les données saisies ou en manipulant les URL.

La modification des données saisies consiste à altérer sans autorisation des données, souvent générées par les utilisateurs, afin d’exploiter les vulnérabilités d’une application. À l’inverse, les vulnérabilités liées à la confusion des URL consistent à modifier des URL pour inciter un système à effectuer des actions imprévues, comme accéder à des ressources non autorisées ou envoyer des requêtes malveillantes.

Sous l’influence de l’attaquant, le serveur envoie des requêtes aux URL manipulées, qui semblent provenir du serveur lui-même, contournant ainsi les mesures de sécurité habituelles. Une attaque SSRF réussie peut donner à l’attaquant accès aux ressources internes, aux bases de données et aux fichiers, et exposer des données sensibles comme des identifiants.

Par exemple, lors de l’un des incidents SSRF les plus marquants, un ancien ingénieur en développement logiciel d’Amazon a exploité une vulnérabilité SSRF qui a exposé 140 000 numéros de sécurité sociale américains, 80 000 numéros de comptes bancaires et 1 million de numéros d’assurance sociale canadiens. La fuite a touché 106 millions de personnes et entraîné 250 millions de dollars US de dommages.

Exemple simple d’attaque SSRF

Pour mieux comprendre les vulnérabilités SSRF, examinons un exemple concret. Dans ce scénario, vous développez une application web qui permet aux utilisateurs de saisir une URL, de récupérer une image à partir de celle-ci et de l’afficher.

Pour suivre l’exemple, clonez ce dépôt GitHub, qui contient le code source de l’application web. Celle-ci utilise Express, un framework Node.js qui simplifie la création de services web. Elle utilise également Axios, une bibliothèque HTTP qui permet d’envoyer des requêtes depuis Node.js.

Pour cloner le dépôt avec Git, exécutez la commande suivante :

git clone https://github.com/davidekete/ssrf.git

Remarque : Git doit être installé sur votre système pour exécuter cette commande.

Après avoir cloné le dépôt GitHub, exécutez la commande suivante pour installer les dépendances :

npm install

Remarque : Node.js et npm doivent être installés pour exécuter cette commande.

L’application comporte trois routes :

  • /upload-image-url permet à un utilisateur de charger une image à partir de son URL. Cette route est accessible publiquement et, à première vue, ne semble présenter aucun risque.

  • /users renvoie toutes les informations sur les utilisateurs de votre application. Cette route ne devrait pas être accessible publiquement.

  • /users/:id/profile renvoie le profil d’un utilisateur donné. Cette route ne devrait pas être accessible publiquement.

Démarrez l’application avec la commande suivante :

node index.js

Lorsque vous envoyez une requête à /upload-image-url avec une URL d’image valide depuis Insomnia (ou tout autre outil de test d’API), vous devriez obtenir la réponse suivante :

Client API affichant une requête d’envoi d’URL d’image vers localhost et une réponse 200 OK contenant le code HTML renvoyé par Imgur

En recevant cette réponse, les utilisateurs malveillants savent que votre serveur effectue des appels d’API en interne à l’aide de l’URL fournie. Ils peuvent alors tester différentes URL pour découvrir la structure interne de votre serveur, ou transmettre des URL comme http://169.254.169.254 ou http://instance-data afin d’accéder aux métadonnées Amazon Web Services (AWS) de votre application, si celle-ci s’exécute sur une instance Amazon Elastic Compute Cloud (Amazon EC2). Ce type d’attaque SSRF est appelé SSRF de base.

Une SSRF de base se produit lorsqu’un attaquant manipule le serveur pour qu’il envoie des requêtes à des ressources imprévues, souvent sans connaître directement la structure interne du serveur. Dans ce cas, l’attaquant peut généralement voir la réponse à la requête.

Un autre type d’attaque SSRF est la SSRF aveugle : l’attaquant envoie des requêtes SSRF, mais n’a pas directement accès à la réponse du serveur. Il s’appuie plutôt sur le comportement de l’application pour confirmer indirectement la réussite de son attaque SSRF.

Par exemple, si un attaquant décide d’essayer l’URL localhost:8050/users, il reçoit la réponse suivante (c’est-à-dire une SSRF de base), qui expose les données de tous vos utilisateurs :

Client API affichant une requête POST pour téléverser une image à partir d’une URL et une réponse 200 OK avec les données JSON renvoyées

Votre code est vulnérable aux attaques SSRF, car il accepte les URL fournies par les utilisateurs sans validation adéquate ni contrôle d’accès. Ceux-ci peuvent donc envoyer des requêtes vers des ressources internes ou privées potentiellement sensibles. Aucun mécanisme de liste d’autorisation ou de blocage de domaines spécifiques n’est non plus en place.

Pour atténuer cette vulnérabilité, votre code doit assainir les données saisies par les utilisateurs, limiter l’accès aux domaines de confiance, utiliser des pare-feu et mettre en place une gestion des erreurs et une surveillance adaptées.

Comment prévenir les vulnérabilités SSRF dans Node.js

Pour prévenir les vulnérabilités SSRF dans votre application Node.js, plusieurs options s’offrent à vous. Dans la section suivante, vous découvrirez des méthodes et des bonnes pratiques utiles.

Utilisez les dernières versions des bibliothèques

Utiliser les dernières versions des bibliothèques est essentiel pour renforcer la sécurité de votre application. Les nouvelles versions incluent souvent des correctifs de sécurité essentiels et des corrections de bogues, qui peuvent rendre votre application moins vulnérable aux attaques courantes comme les SSRF.

Toutefois, lors des mises à jour, il est essentiel de tenir compte des problèmes de compatibilité, des changements susceptibles de rompre la compatibilité et de la rétrocompatibilité. Surveillez les cycles d’abandon, mettez à jour progressivement les bases de code volumineuses et analysez régulièrement les dépendances pour détecter d’éventuelles vulnérabilités, afin de maintenir une application sécurisée et bien entretenue.

Utilisez Snyk pour mettre à niveau vos bibliothèques, maintenir vos dépendances à jour et les protéger des vulnérabilités de sécurité publiquement connues.

Utilisez un pare-feu

Un pare-feu est un système de sécurité réseau qui joue le rôle de barrière protectrice et surveille et contrôle le trafic réseau en fonction de règles prédéfinies.

Pour prévenir les attaques SSRF à l’aide de pare-feu, vous pouvez déployer un pare-feu applicatif web (WAF) afin d’inspecter et de bloquer les requêtes malveillantes. Pour cela, créez une liste d’autorisation de domaines de confiance et bloquez les URL ou adresses IP suspectes.

Assainissez les données saisies par les utilisateurs

L’assainissement des données saisies est une pratique de sécurité qui consiste à nettoyer et à modifier les données fournies par les utilisateurs afin qu’elles puissent être traitées sans risque par votre application. Son principal objectif est de prévenir les vulnérabilités de sécurité liées aux données non fiables ou malveillantes.

Vous pouvez prévenir les attaques SSRF en assainissant toutes les données saisies par les utilisateurs, afin de vérifier que les URL sont correctement formatées et ne contiennent pas de caractères inattendus avant leur traitement par votre application.

L’assainissement des données saisies peut contribuer à garantir que les URL sont correctement formatées, mais ne doit pas être utilisé seul.

Imposez des schémas d’URL

Vous pouvez également prévenir les vulnérabilités SSRF en imposant certains schémas d’URL. En définissant les schémas autorisés par votre application (par exemple, HTTP et HTTPS), vous pouvez empêcher les utilisateurs de saisir des URL utilisant des schémas potentiellement dangereux ou indésirables (par exemple file:// et ftp://).

Pour mettre cette mesure en œuvre dans l’application clonée précédemment, vérifiez explicitement que l’URL fournie commence par un schéma autorisé, généralement http:// ou https://. Si ce n’est pas le cas, vous pouvez la rejeter :

const validURLPattern = /^https?:\/\//;
const imageURL = req.body.imageURL;

if (!imageURL || !validURLPattern.test(imageURL)) {
  return res.status(400).send("Invalid or missing image URL");
}

Créez une liste d’autorisation de domaines de confiance

La création d’une liste d’autorisation de domaines de confiance prévient les vulnérabilités SSRF en permettant uniquement les requêtes vers des domaines spécifiques, réputés sûrs et nécessaires à votre application.

Pour mettre cette mesure en œuvre dans l’application clonée précédemment, créez un tableau contenant les domaines auxquels vous faites confiance et vers lesquels votre application peut envoyer des requêtes (dans une application réelle, une méthode plus robuste peut être nécessaire). Il doit s’agir de domaines avec lesquels votre application interagit et qu’elle considère comme sûrs.

Avant d’envoyer une requête vers l’URL fournie par l’utilisateur, vérifiez ensuite si elle correspond à l’un des domaines de confiance de votre liste. Si ce n’est pas le cas, bloquez la requête. Une fois ces changements mis en œuvre, votre route /upload-image-url devrait ressembler à ceci :

app.post("/upload-image-url", async (req, res) => {
  try {
    const trustedDomains = [
      "https://unsplash.com/",
      "https://example.com",
      "https://pexels.com/",
    ];

    const imageURL = req.body.imageURL;

    if (!imageURL) {
      return res.status(400).send("Image URL is required");
    }

    let isTrustedDomain = false;

    for (const domain of trustedDomains) {
      if (imageURL.startsWith(domain)) {
        isTrustedDomain = true;
        break;
      }
    }

    if (!isTrustedDomain) {
      return res.status(403).send("Access to this domain is not permitted.");
    }

    // Proceed with the request to the trusted domain.
    const image = await axios.get(imageURL);

    return res.json({
      response: "Image uploaded successfully",
      image: image.data,
    });
  } catch (error) {
    if (axios.isAxiosError(error)) {
      return res.status(error.response.status).send(error.response.data);
    }

    res.status(500).send("Something went wrong");
  }
});

Ce code modifie la route /upload-image-url en ajoutant un tableau de domaines autorisés, en vérifiant si l’URL fournie par l’utilisateur figure dans la liste d’autorisation et en rejetant la requête si ce n’est pas le cas.

Utilisez l’extension IDE de Snyk pour détecter les vulnérabilités

Snyk est un outil de sécurité populaire qui peut vous aider à identifier et à corriger les vulnérabilités, notamment les SSRF, dans les bibliothèques open source. Snyk s’intègre à différents environnements de développement et IDE, dont Visual Studio Code (VS Code).

Pour installer l’extension IDE de Snyk dans VS Code, ouvrez la vue Extensions en cliquant sur l’icône en forme de carré dans la barre latérale gauche ou en appuyant sur Ctrl + Shift + X (ou Cmd + Shift + X sur macOS) :

Vue Extensions de Visual Studio Code affichant une recherche « Snyk » et les détails de l’extension Snyk Security installée

Recherchez « Snyk » dans la Marketplace des extensions et cliquez sur le bouton Install à côté de l’extension Snyk :

Visual Studio Code affiche la page de l’extension Snyk Security, avec des détails sur l’analyse du code et les options d’installation

Après avoir installé l’extension, vous devez l’authentifier avec votre compte Snyk. Si vous n’avez pas de compte Snyk, inscrivez-vous dès maintenant. Cliquez sur l’icône Snyk et connectez-vous avec vos identifiants Snyk.

Ouvrez ensuite dans VS Code le dépôt du projet que vous avez cloné. Une invite vous demandera si Snyk peut faire confiance à ces dossiers : cliquez sur Trust folders and continue :

La boîte de dialogue d’avertissement de Snyk indique que l’analyse peut exécuter du code et recommande de n’analyser que des dossiers de confiance. Elle propose d’autoriser ou de refuser des dossiers.

Des lignes ondulées rouges devraient apparaître à certains endroits de votre code présentant des vulnérabilités de sécurité (c’est-à-dire axios.get à la ligne 19). Lorsque vous survolez l’une de ces lignes, une fenêtre modale explique la vulnérabilité.

Code JavaScript dans VS Code avec un avertissement de sécurité signalant une vulnérabilité SSRF dans une requête axios.get.

Vous pouvez également cliquer sur l’icône Snyk et sélectionner CODE SECURITY pour afficher les problèmes de sécurité. Lorsque vous sélectionnez une vulnérabilité, Snyk ouvre la barre latérale gauche et fournit des exemples de code pour vous aider à la corriger.

Panneau de vulnérabilités de Snyk Code mettant en évidence une vulnérabilité de falsification de requête côté serveur dans du code Node.js, où axios demande une image à partir d’une URL fournie par l’utilisateur

Conclusion

Dans cet article, vous avez découvert qu’il est essentiel de protéger vos applications Node.js contre les attaques SSRF, ainsi que des stratégies et bonnes pratiques pour y parvenir.

En utilisant les dernières versions des bibliothèques, en imposant des schémas d’URL, en mettant en place des listes d’autorisation et en utilisant des outils de sécurité comme Snyk, vous pouvez réduire considérablement le risque de vulnérabilités SSRF dans vos applications. De plus, en intégrant Snyk à votre workflow de développement, vous pouvez détecter efficacement les SSRF et autres vulnérabilités dans votre code avant sa mise en production, renforcer votre code et protéger vos systèmes contre les attaques potentielles.

N’attendez plus ! Commencez dès aujourd’hui à protéger vos applications avec Snyk !

Lancez-vous dans le Capture the Flag

Découvrez comment résoudre des défis Capture the Flag en regardant à la demande notre atelier virtuel d’initiation.

Lire la suite

feature insights context
Blog

Les attaques autonomes sont déjà là. La défense doit suivre leur rythme.

Les attaquants autonomes réduisent la fenêtre de défense. Découvrez comment la découverte, la correction, la validation et la prévention continues peuvent aider les équipes de sécurité à suivre le rythme.

illustration hero ai
Blog

L’ouragan de l’IA est là

L’IA accélère à la fois la création de logiciels et les cyberattaques. Les dirigeants doivent sécuriser les agents et le code dès leur conception, appliquer des contrôles à l’exécution et valider les défenses de manière indépendante.

feature insights context
Blog

La prévention est-elle essentiellement un problème résolu ?

La prévention dans le code généré par les agents est résolue sur le plan architectural, mais le défi reste de choisir des contrôles qui protègent la sécurité sans ralentir le développement.