Files
ENI-JSAdvanced_13/README.md
2025-12-18 15:27:04 +01:00

5.6 KiB

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 :
    npm install
    
  2. Lancer le serveur :
    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) :

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) :

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) :

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).
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: <script>alert('Hacked')</script>), 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.
flowchart TD
    A["Input: '<script>alert'"] --> B["Stocké en BDD tel quel"];
    B --> C["Requête GET pour la note"];
    C --> D["Serveur envoie la donnée brute au navigateur"];
    D --> E["Navigateur interprète le HTML: exécution du script"];

Flux sécurisé (cible) :

flowchart TD
    A["Input: '<script>alert'"] --> B["Stocké en BDD tel quel"];
    B --> C["Requête GET pour la note"];
    C --> D["Serveur 'échappe' les caractères: '&lt;script&gt;...'"];
    D --> E["Navigateur affiche le texte 'échappé' sans l'exécuter"];

Bonus (pour aller plus loin)

Si vous avez terminé les corrections principales :

  • Security Headers (OWASP A02:2025 - Security Misconfiguration) : utilisez le middleware helmet pour ajouter automatiquement les en-têtes HTTP de sécurité.
  • Authentification robuste : remplacez l'envoi brut de l'userId par un véritable mécanisme de token JWT (JSON Web Token).

Bon courage !