From a2a11197a96166160b8b525391a7dc755819a6bb Mon Sep 17 00:00:00 2001 From: Johan Date: Thu, 18 Dec 2025 15:27:04 +0100 Subject: [PATCH] First commit --- .gitignore | 2 + README.md | 132 ++ package-lock.json | 3359 +++++++++++++++++++++++++++++++++++++++++++++ package.json | 22 + server.js | 62 + 5 files changed, 3577 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 server.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a440d02 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/.idea +node_modules \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..e2b3826 --- /dev/null +++ b/README.md @@ -0,0 +1,132 @@ +# TP Fix'it - audit & sécurisation + +## Contexte de la mission + +Vous venez de rejoindre l'équipe technique d'une jeune startup, **"SafeNote"**. +Le développeur précédent, pressé par les délais, a quitté l'entreprise précipitamment la semaine dernière. Il a laissé derrière lui un prototype fonctionnel (le fichier `server.js`) qui permet aux utilisateurs de s'inscrire et de gérer des notes privées. + +**Le problème ?** +Le code est fonctionnel, mais **catastrophique** en termes de sécurité. Votre CTO a identifié plusieurs failles critiques du **Top 10 OWASP** et vous charge de nettoyer ce code avant la mise en production. + +--- + +## Installation & Démarrage + +Assurez-vous d'avoir lu le fichier `server.js` (fourni) à la racine de votre projet. + +1. **Initialiser le projet et installer les dépendances :** + Dans votre terminal, exécutez les commandes suivantes : + ```bash + npm install + ``` +2. Lancer le serveur : + ```bash + nodemon server.js + ``` +3. Tester l'application actuelle : L'API écoute sur le port 3000. Vous pouvez utiliser Postman à cet effet. + - POST `/login` (Body JSON : `{"username": "admin", "password": "supersecret"}`) + - POST `/notes` (Body JSON : `{"userId": 1, "content": "Ma note"}`) + - GET `/notes/1` + +--- + +## Objectifs de la mission + +Votre mission est d'identifier et de corriger **4 failles majeures**. + +### 1. Stopper l'hémorragie SQL (OWASP A05:2025 Injection) +Actuellement, la connexion est vulnérable. Un attaquant peut se connecter sans mot de passe en utilisant une injection SQL simple dans le champ `username` (ex: `admin' --`). +* **Tâche :** remplacez la concaténation de chaînes par des **requêtes préparées** (Prepared Statements) de SQLite. + +**Flux de l'attaque (actuel) :** + +```mermaid +flowchart TD + A["Input utilisateur: 'admin' --'"] --> B["Serveur concatène la requête: '...WHERE user = '' + 'admin' --' + ''...'"]; + B --> C["Requête SQL exécutée: '...WHERE user = 'admin' -- ...'"]; + C --> D{Base de données}; + D -- "Commentaire SQL '--' ignore le mdp" --> E[Accès accordé]; +``` + +**Flux sécurisé (cible) :** + +```mermaid +flowchart TD + A["Input utilisateur: 'admin' --'"] --> B["Serveur utilise une requête préparée: '...WHERE user = ?'"]; + B --> C["Serveur envoie la donnée 'admin' --' séparément"]; + C --> D{Base de données}; + D -- "La donnée est traitée comme du texte, pas du code" --> E[Accès refusé]; +``` + +### 2. Protéger les mots de Passe (OWASP A04:2025 Cryptographic Failures) +Les mots de passe sont stockés en clair dans la base de données (`supersecret`, `password123`). C'est inacceptable. +* **Tâche :** modifiez le code pour hacher les mots de passe avec **bcrypt** lors de leur création (simulation) et vérifier le hash lors du login. + +**Flux de vérification sécurisé (cible) :** + +```mermaid +flowchart TD + subgraph Inscription + P1["Mdp utilisateur: 'password123'"] --> P2["bcrypt.hash 'password123'"]; + P2 --> P3["Stocke le hash '$2b$10$...' en BDD"]; + end + subgraph Connexion + A["Input: 'password123'"] --> B["Récupère le hash '$2b$10$...' de la BDD"]; + B --> C["Compare l'input au hash via 'bcrypt.compare'"]; + C --> D{Match?}; + D -- "Oui" --> E[Accès accordé]; + D -- "Non" --> F[Accès refusé]; + end +``` + +### 3. Cloisonner les données (OWASP A01:2025 Broken Access Control) +Actuellement, un utilisateur peut lire les notes de n'importe qui en changeant simplement l'ID dans l'URL (ex: passer de `/notes/1` à `/notes/2`). C'est une faille **IDOR** (Insecure Direct Object Reference). +* **Tâche :** assurez-vous que l'utilisateur qui demande la note est bien le **propriétaire** de cette note. + * *Indice :* vous devrez probablement simuler ou implémenter une vérification de l'utilisateur courant (via un middleware ou une vérification d'ID). + +```mermaid +flowchart TD + A["Requête: GET /notes/5"] -- "Session: utilisateurId = 1" --> B["Serveur récupère la note 5"]; + B --> C{Note 5 existe?}; + C -- "Non" --> D[Réponse: 404 Not Found]; + C -- "Oui" --> E["Récupère le propriétaire: 'note.proprietaireId = 2'"]; + E --> F{"Le 'proprietaireId' 2 correspond à 'l'utilisateurId' 1?"}; + F -- "Non (IDOR bloqué)" --> G[Réponse: 403 Forbidden / 404 Not Found]; + F -- "Oui" --> H[Réponse: Affiche la note 5]; +``` + +### 4. Nettoyer les sorties (OWASP A05:2025 Injection / XSS) +Si une note contient du code HTML/JS (ex: ``), l'application l'exécute tel quel dans le navigateur. +* **Tâche :** mettez en place un **encodage de sortie** (Output Encoding) ou utilisez une bibliothèque d'échappement pour neutraliser le HTML avant de le renvoyer au client. + +```mermaid +flowchart TD + A["Input: '