Sécuriser son API Node.js : se protéger contre les attaques courantes

Par adelaa, 22 mars, 2025
Node.js

Tout au long de cette série, nous avons construit une API avec Node.js et Express, étape par étape. Nous avons mis en place un serveur, créé des routes, ajouté un système de gestion de fichiers, intégré des rôles pour restreindre l’accès, et optimisé les performances.

Mais une API exposée sur internet est aussi une cible potentielle d’attaques. Une mauvaise gestion de la sécurité peut exposer les données des utilisateurs, voire le serveur lui-même. C’est pourquoi, dans ce dernier article, nous allons voir comment protéger notre API contre les attaques les plus fréquentes.

Avant cela, faisons un récapitulatif du travail accompli jusqu’ici.

1. Récapitulatif des six premières semaines

  • Semaine 1 – Introduction à Node.js
    Création d’un premier serveur avec Node.js et compréhension de son fonctionnement côté backend.

  • Semaine 2 – Créer un serveur backend avec Express
    Mise en place d’un serveur RESTful avec Express et création de routes de base.

  • Semaine 3 – Gestion des routes et API REST
    Manipulation des requêtes HTTP (GET, POST, PUT, DELETE) et structuration d’une API.

  • Semaine 4 – Lecture et écriture de fichiers
    Utilisation du module fs pour interagir avec les fichiers du système (création, lecture, suppression).

  • Semaine 5 – Upload de fichiers avec Multer
    Traitement des fichiers envoyés par formulaire, filtrage et stockage sécurisé.

  • Semaine 6 – Gestion des rôles et permissions
    Mise en place d’un système d’authentification avec JWT et protection des routes selon les rôles des utilisateurs.

2. Se protéger contre les attaques courantes

2.1 Attaque par injection (SQL ou NoSQL)

L'injection est l’une des attaques les plus répandues. Elle consiste à insérer du code malveillant dans une requête, généralement via les champs de formulaire ou les paramètres d’URL. Si les données ne sont pas filtrées correctement, ce code peut manipuler la base de données, révéler des informations sensibles, ou même supprimer des données.

Exemple d’injection NoSQL (si vous utilisez MongoDB) :

{ "email": { "$gt": "" } }

Cela peut tromper une requête de connexion et donner un accès non autorisé.

Solutions :

  • Valider les données entrantes avec des règles strictes (format, longueur, type).
  • Utiliser une bibliothèque comme express-validator pour filtrer chaque champ de manière automatique.
npm install express-validator

Exemple du code :

const { body } = require('express-validator');
app.post('/connexion', [
  body('email').isEmail(),
  body('password').isLength({ min: 6 })
], (req, res) => {
  // Traitement sécurisé
});

2.2 Attaque XSS (Cross-Site Scripting)

Une attaque XSS consiste à injecter du code JavaScript dans une application, souvent via un champ de texte (comme un commentaire). Ce code malveillant s’exécute ensuite dans le navigateur d’un autre utilisateur, permettant à l’attaquant de voler des cookies, rediriger vers des sites frauduleux ou modifier l’interface.

Exemple :
Un utilisateur malveillant poste un commentaire comme :

<script>alert('hack');</script>

Solutions :

  • Échapper ou nettoyer tout contenu fourni par l’utilisateur avant de l’enregistrer ou l’afficher.
  • Utiliser un middleware comme xss-clean pour filtrer automatiquement les entrées.
npm install xss-clean

Exemple du code :

const xss = require('xss-clean');
app.use(xss());

2.3 Attaque par force brute (brute force login)

Cette attaque consiste à tester un grand nombre de combinaisons (identifiants, mots de passe) jusqu’à trouver une combinaison valide. Elle est souvent utilisée contre les formulaires de connexion.

Problèmes causés :

  • Ralentissement du serveur (nombre élevé de requêtes).
  • Possibilité d’accès non autorisé si les mots de passe sont faibles.

Solutions :

  • Limiter le nombre de tentatives par IP à l’aide de express-rate-limit.
  • Verrouiller temporairement l’accès après plusieurs échecs.
npm install express-rate-limit

Exemple du code :

const rateLimit = require('express-rate-limit');

const limiter = rateLimit({
    windowMs: 15 * 60 * 1000, // 15 minutes
    max: 100, // max 100 requêtes par IP
    message: 'Trop de requêtes. Réessayez plus tard.'
});

app.use(limiter);

3. Recommandations supplémentaires pour aller plus loin

Voici quelques bonnes pratiques générales pour améliorer encore la sécurité de votre API :

3.1 Forcer l'utilisation de HTTPS

Assurez-vous que toutes les communications passent par HTTPS (et non HTTP simple). Cela chiffre les données échangées entre le client et le serveur, empêchant les attaques de type "Man in the Middle".

3.2 Garder vos dépendances à jour

Les bibliothèques comme express, jsonwebtoken, bcrypt évoluent et corrigent régulièrement des failles. Utilisez régulièrement :

npm audit fix

Et surveillez les mises à jour critiques.

3.3 Ne jamais exposer vos clés secrètes

Utilisez dotenv et un fichier .env pour stocker des informations sensibles comme vos clés JWT, mots de passe de base de données, etc.
Ne jamais les inclure en dur dans le code source.

3.4 Utiliser des permissions claires sur les routes

Comme vu à la semaine 6, définissez des rôles précis et ne laissez aucune route critique sans protection.

3.5 Journaliser les accès et erreurs

Ajoutez un système de log (comme winston) pour surveiller les comportements anormaux, les erreurs critiques, ou les tentatives d’intrusion.

4. Sources

  1. OWASP - API Security Top 10 : https://owasp.org/API-Security/ (page consultée le 21 mars 2025)
  2. Helmet.js - Documentation officielle : https://helmetjs.github.io/ (page consultée le 21 mars 2025)
  3. Mozilla Developer Network - HTTP Security Best Practices : https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers (page consultée le 21 mars 2025)

Conclusion

Nous avons construit une API Node.js complète et fonctionnelle, en explorant semaine après semaine des aspects essentiels :

  • Création d’un serveur,
  • Construction d’une API REST,
  • Gestion des fichiers,
  • Authentification et permissions,
  • Optimisation des performances,
  • Sécurisation contre les menaces.

Dans ce dernier article, nous avons appris à protéger l’API contre les attaques les plus courantes, un passage obligé pour tout projet en production.

Merci d’avoir suivi cette série jusqu’au bout ! J’espère qu’elle vous a permis de mieux comprendre comment créer une API sécurisée, robuste et prête à être utilisée dans un vrai projet. À bientôt pour de nouveaux défis !

Étiquettes

Commentaires3

abenkarrouch

il y a 1 jour 19 heures

Très bon blog mais je voulais savoir quels outils tu recommanderais pour tester et auditer la sécurité de l'API une fois qu'elle soit déployée ?

alouragli

il y a 1 jour 17 heures

Salut Monsieur Aziz, Très beaux articles sur Node.js. Merci d'avoir partagé comment sécuriser son API Node.js en se protégeant contre les attaques courantes. Moi-même, j'ai écrit des articles sur NodeJs. Dans mes prochains projets utilisant cette technologie, je suivrai tes conseils, comme l'utilisation de express-validator pour se protéger des attaques par injection, xss-clean pour se protéger des attaques XSS (Cross-Site Scripting), et express-rate-limit pour se protéger des attaques par force brute (brute force login). Merci aussi pour tes recommandations, qui sont utiles et très compréhensibles. De plus, je t'invite à aller me laisser un petit commentaire pour me dire ce que tu en penses.