2025-12-18 15:20:06 +01:00
2025-12-18 15:20:06 +01:00
2025-12-18 15:20:06 +01:00
2025-12-18 15:20:06 +01:00
2025-12-18 15:20:06 +01:00
2025-12-18 15:20:06 +01:00
2025-12-18 15:20:06 +01:00
2025-12-18 15:20:06 +01:00
2025-12-18 15:20:06 +01:00

Démonstration OWASP A02 : mauvaise configuration de sécurité (CORS)

Objectif

Comprendre la faille de sécurité OWASP A02:2025 (Security Misconfiguration) à travers une démonstration concrète sur CORS (Cross-Origin Resource Sharing).

Dans cet exercice, vous n'allez pas coder. Vous allez manipuler la configuration d'un serveur Express.js pour observer la différence entre une configuration vulnérable et une configuration sécurisée.

Contexte

Nous avons deux projets:

  • cors: un serveur Express (back-end) qui tourne sur http://localhost:3000.
  • sous-répertoire client-test: un simple fichier index.html (front-end) qui sera servi par votre IDE (sur un port dynamique, ex: http://localhost:63342).

Le client (d'une certaine origine) va tenter d'appeler l'API (sur une autre origine). Nous allons voir comment CORS peut bloquer ou autoriser cet appel.

flowchart LR
    subgraph "Client (Navigateur)"
        ClientApp["index.html<br>Origine: http://localhost:63342"]
    end
    subgraph "Serveur (API)"
        ServerApp["app.js (Express)<br>Origine: http://localhost:3000"]
    end
    ClientApp -- "Tente d'appeler l'API" --> ServerApp

Instructions

Mise en place

  1. Ouvrez un terminal et placez-vous dans le dossier cors.
  2. Installez les dépendances:
    npm install
    
  3. Ouvrez le fichier client-test/index.html avec votre IDE (clic droit > "Run 'index.html'" ou similaire).
  4. Gardez cette page navigateur ouverte. Elle vous indique sa propre origine (ex: http://localhost:63342). Notez-la.

Partie 1 : la vulnérabilité (origin: '*')

Dans cette partie, nous allons voir pourquoi origin: '*' est une mauvaise configuration de sécurité.

  1. Ouvrez le fichier cors/app.js.
  2. Vérifiez que c'est bien corsOptions_VULNERABLE qui est activé:
    // DÉCOMANDEZ L'OPTION QUE VOUS VOULEZ TESTER :
    
    app.use(cors(corsOptions_VULNERABLE)); // <--- CETTE LIGNE DOIT ÊTRE ACTIVE
    //
    // app.use(cors(corsOptions_SECURISEE)); 
    
  3. Lancez le serveur API dans votre terminal (depuis le dossier cors):
    nodemon ./bin/www
    
    (Le serveur tourne maintenant sur http://localhost:3000)
  4. Retournez sur votre page index.html dans le navigateur.
  5. Cliquez sur le bouton "Appeler l'API".

Résultat attendu: succès. La page affiche les données JSON de l'API.

Pourquoi c'est une faille: L'API a répondu. C'est normal, car origin: '*' signifie "J'autorise n'importe quel site web sur Internet à m'appeler". Si cette page était un site de phishing, elle aurait pu récupérer vos données. C'est une faille A02.

sequenceDiagram
    participant Client as "Client<br>localhost:63342"
    participant Serveur as "Serveur<br>localhost:3000"
    Client->>Serveur: "1. Requete API (Origin: localhost:63342)"
    Serveur-->>Serveur: 2. Verifie config CORS: origin: '*'
    Serveur->>Client: "3. Reponse API (Access-Control-Allow-Origin: *)"
    Client-->>Client: 4. Navigateur autorise<br>Succes!

Partie 2 : la correction (Whitelist)

Maintenant, nous allons corriger la faille en n'autorisant que notre client légitime.

  1. Arrêtez le serveur API (Ctrl+C dans le terminal).

  2. Dans cors/app.js, modifiez les lignes app.use pour activer la version sécurisée:

    // DÉCOMANDEZ L'OPTION QUE VOUS VOULEZ TESTER :
    
    // app.use(cors(corsOptions_VULNERABLE)); 
    //
    app.use(cors(corsOptions_SECURISEE)); // <--- CETTE LIGNE DOIT ÊTRE ACTIVE
    
  3. Dans ce même fichier, juste au-dessus, modifiez la variable corsOptions_SECURISEE pour qu'elle corresponde exactement à l'origine affichée sur votre page index.html.

    Exemple: si votre page affiche http://localhost:63342, le code doit être:

    const corsOptions_SECURISEE = {
      origin: 'http://localhost:63342'
    };
    
  4. Sauvegardez app.js et relancez le serveur API:

    nodemon ./bin/www
    
  5. Retournez sur votre page index.html et rafraîchissez-la (Ctrl+R ou Cmd+R).

  6. Cliquez sur le bouton "Appeler l'API".

Résultat attendu: succès. Les données s'affichent, comme dans la partie 1.

Alors, quelle est la différence ? La différence est que maintenant, seule cette origine est autorisée. Pour le prouver, faisons un dernier test.


Partie 3 : la preuve de la sécurité

Prouvons que notre API rejette bien les origines inconnues.

  1. Arrêtez le serveur API (Ctrl+C).
  2. Dans cors/app.js, modifiez corsOptions_SECURISEE pour y mettre une fausse origine:
    const corsOptions_SECURISEE = {
      origin: '[http://site-malveillant.com](http://site-malveillant.com)'
    };
    
  3. Sauvegardez app.js et relancez le serveur API:
    nodemon ./bin/www
    
  4. Retournez sur votre page index.html (qui tourne toujours sur http://localhost:63342) et rafraîchissez-la.
  5. Ouvrez la console de développement (F12) et allez dans l'onglet "Console".
  6. Cliquez sur le bouton "Appeler l'API".

Résultat attendu: échec. La page affiche ERREUR: Failed to fetch.

Pourquoi c'est corrigé: Regardez la console du navigateur. Vous y verrez une erreur CORS en rouge. Le navigateur a bloqué la requête car:

  • Le client (http://localhost:63342) a demandé des données.
  • Le serveur a répondu: "Je n'autorise que http://site-malveillant.com".
  • Le navigateur a comparé les deux, a vu qu'ils ne correspondaient pas, et a bloqué la réponse pour protéger l'utilisateur.

Nous avons corrigé la faille A02:2025, notre API ne parle désormais qu'aux clients qu'elle connaît et approuve.

sequenceDiagram
    participant Client as "Client<br>localhost:63342"
    participant Serveur as "Serveur<br>localhost:3000"
    Client->>Serveur: "1. Requete API (Origin: localhost:63342)"
    Serveur-->>Serveur: 2. Verifie config CORS: origin: 'http://site-malveillant.com'
    Serveur->>Client: "3. Reponse API (Access-Control-Allow-Origin: http://site-malveillant.com)"
    Client-->>Client: 4. Navigateur compare:<br>Requete "localhost:63342" != Reponse "site-malveillant.com"
    Client-->>Client: 5. ECHEC: Erreur CORS
Description
No description provided
Readme 51 KiB
Languages
JavaScript 61.8%
HTML 38.2%