var express = require('express'); var router = express.Router(); var bcrypt = require('bcrypt'); var rateLimit = require('express-rate-limit'); // --- Base de données simulée --- const db = { users: [ { id: 1, username: 'admin', password_vulnerable: 'password123', hashedPassword: bcrypt.hashSync('password123', 12) } ] }; /* GET home page */ router.get('/', function(req, res, next) { res.render('index', { title: 'Express' }); }); // ========================================================== // ## 👎 DÉMONSTRATION VULNÉRABLE (A07) // ========================================================== router.post('/login-vulnerable', (req, res) => { // !! REPOSE SUR express.json() et express.session() définis dans app.js !! const { username, password } = req.body; const user = db.users.find(u => u.username === username); // FAILLE 1 : Énumération de comptes if (!user) { return res.status(404).send('Erreur : Utilisateur non trouvé.'); } // FAILLE 2 : Stockage et comparaison en clair if (user.password_vulnerable !== password) { return res.status(400).send('Erreur : Mot de passe incorrect.'); } // FAILLE 3 : Fixation de session req.session.userId = user.id; req.session.username = user.username; console.log(`[VULNÉRABLE] Session AVANT login: ${req.sessionID}`); console.log(`[VULNÉRABLE] Session APRÈS login: ${req.sessionID} (INCHANGÉE)`); res.send(`Connexion (vulnérable) réussie pour ${user.username} !`); }); // ========================================================== // ## DÉMONSTRATION CORRIGÉE (A07) // ========================================================== // CORRECTION 4 : Limitation de tentatives (Rate Limiting) const loginLimiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes max: 10, // Limite à 10 tentatives par IP par fenêtre de 15 min message: 'Trop de tentatives de connexion. Réessayez dans 15 minutes.' }); // Applique le limiteur uniquement à ce point de terminaison router.use('/login-securise', loginLimiter); router.post('/login-securise', async (req, res) => { // !! REPOSE SUR express.json() et express.session() définis dans app.js !! const { username, password } = req.body; const user = db.users.find(u => u.username === username); // CORRECTION 1 & 2 : Pas d'énumération + Hachage fort const match = user ? await bcrypt.compare(password, user.hashedPassword) : false; if (!match) { return res.status(401).send('Identifiants invalides.'); } // CORRECTION 3 : Régénération de la session const oldSessionId = req.sessionID; req.session.regenerate((err) => { if (err) { console.error(err); return res.status(500).send('Erreur lors de la régénération de session.'); } req.session.userId = user.id; req.session.username = user.username; console.log(`[SÉCURISÉ] Session AVANT login: ${oldSessionId}`); console.log(`[SÉCURISÉ] Session APRÈS login: ${req.sessionID} (CHANGÉE)`); res.send(`Connexion (sécurisée) réussie pour ${user.username} !`); }); }); // --- Point de déconnexion --- router.get('/logout', (req, res) => { // !! REPOSE SUR express.session() défini dans app.js !! req.session.destroy((err) => { if (err) { return res.status(500).send('Impossible de se déconnecter.'); } res.clearCookie('connect.sid'); // Nom par défaut du cookie de session res.send('Déconnecté avec succès.'); }); }); module.exports = router;