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 modulefs
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
- OWASP - API Security Top 10 : https://owasp.org/API-Security/ (page consultée le 21 mars 2025)
- Helmet.js - Documentation officielle : https://helmetjs.github.io/ (page consultée le 21 mars 2025)
- 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 !
Commentaires3
Sécurité post-développment
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 ?
Salut Monsieur Aziz,Très…
Salut Monsieur Aziz,
Salut Monsieur Aziz,Très…
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.