const express = require('express'); const sqlite3 = require('sqlite3').verbose(); const bcrypt = require('bcrypt'); const helmet = require('helmet'); const escape = require('escape-html'); const jwt = require('jsonwebtoken'); const app = express(); app.use(express.json()); // BDD simulée en mémoire const db = new sqlite3.Database(':memory:'); db.serialize(() => { db.run("CREATE TABLE users (id INTEGER PRIMARY KEY, username TEXT, password TEXT)"); db.run("CREATE TABLE notes (id INTEGER PRIMARY KEY, user_id INTEGER, content TEXT)"); // Mot de passe stocké en clair (Faille 1) db.run("INSERT INTO users (username, password) VALUES ('admin', 'supersecret')"); db.run("INSERT INTO users (username, password) VALUES ('alice', 'password123')"); db.run("INSERT INTO notes (user_id, content) VALUES (2, 'Mon secret personnel')"); }); // Route de connexion app.post('/login', (req, res) => { const { username, password } = req.body; // Faille 2 : Injection SQL (Concaténation directe) const query = "SELECT * FROM users WHERE username = '" + username + "' AND password = '" + password + "'"; db.get(query, (err, row) => { if (err) return res.status(500).send(err.message); if (row) { res.json({ message: "Connecté", userId: row.id }); } else { res.status(401).send("Échec"); } }); }); // Route pour lire une note app.get('/notes/:id', (req, res) => { // Faille 3 : Broken Access Control (IDOR) // On ne vérifie pas si la note appartient à l'utilisateur qui la demande const query = `SELECT * FROM notes WHERE id = ${req.params.id}`; db.get(query, (err, row) => { if (row) { // Faille 4 : XSS Réfléchi/Stocké (Pas d'échappement de la sortie) res.send(`