First commit
This commit is contained in:
153
README.md
Normal file
153
README.md
Normal file
@@ -0,0 +1,153 @@
|
||||
# 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<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:
|
||||
```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<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:
|
||||
```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<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
|
||||
```
|
||||
Reference in New Issue
Block a user