# 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. ```mermaid flowchart LR subgraph "Client (Navigateur)" ClientApp["index.html
Origine: http://localhost:63342"] end subgraph "Serveur (API)" ServerApp["app.js (Express)
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: ```bash 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é: ```javascript // 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`): ```bash 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. ```mermaid sequenceDiagram participant Client as "Client
localhost:63342" participant Serveur as "Serveur
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
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: ```javascript // 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:* ```javascript const corsOptions_SECURISEE = { origin: 'http://localhost:63342' }; ``` 4. Sauvegardez `app.js` et relancez le serveur API: ```bash 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: ```javascript const corsOptions_SECURISEE = { origin: '[http://site-malveillant.com](http://site-malveillant.com)' }; ``` 3. Sauvegardez `app.js` et relancez le serveur API: ```bash 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. ```mermaid sequenceDiagram participant Client as "Client
localhost:63342" participant Serveur as "Serveur
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:
Requete "localhost:63342" != Reponse "site-malveillant.com" Client-->>Client: 5. ECHEC: Erreur CORS ```