Commit 152e37fe authored by Fabrice's avatar Fabrice
Browse files

modification fiche token

parent aa89bbb2
Loading
Loading
Loading
Loading
+216 −94
Original line number Diff line number Diff line
# Fiche récapitulative : Tokens et Cookies

## 1. Définitions Token et Cookie 
Un **cookie** est un petit fichier stocké dans le navigateur contenant des données utilisées par un site web. Il est envoyé automatiquement au serveur (à chaque requête HTTP).

glpat-As_Mdsh2zyNDoKTRoqan
Un **token** est une chaîne de caractères utilisée pour l'authentification et l'autorisation dans les applications web et API. En fonction des besoins (authentification, protection des formulaires, API sécurisées...), différents tokens peuvent être combinés pour renforcer la sécurité d'une application.

## 1. Qu'est-ce qu'un Token ?
Un **token** est une chaîne de caractères utilisée pour l'authentification et l'autorisation dans les applications web et API.
### **Identification vs Authentification vs Autorisation**

En fonction des besoins (authentification, protection des formulaires, API sécurisées...), différents tokens peuvent être combinés pour renforcer la sécurité d’une application.
| **Concept**         | **Question clé**       | **Action**                                       | **Exemple**                                                                 |
|----------------------|------------------------|-------------------------------------------------|----------------------------------------------------------------------------|
| **Identification**  | **« Qui êtes-vous ? »**| Déclarer son identité.                          | Entrer un nom d'utilisateur ou un email (ex: `johndoe@example.com`).       |
| **Authentification**| **« Prouvez-le ! »**   | Vérifier que vous êtes bien cette personne.     | Saisir un mot de passe, un code OTP, ou scanner une empreinte digitale.    |
| **Autorisation**     | **« Que pouvez-vous faire ? »** | Définir ce que l'utilisateur est autorisé à faire ou à voir. | Accéder à vos fichiers ou modifier des données selon vos permissions.     |

### Tokens et lois (RGPD)
Prenons l'exemple d'une application bancaire :
1. **Identification** : Vous entrez votre **identifiant client**.
2. **Authentification** : Vous utilisez votre **mot de passe** ou un **code reçu par SMS** pour prouver que vous êtes bien cet utilisateur.
3. **Autorisation** : Une fois connecté(e), vous pouvez :
   - Accéder à vos comptes et transactions (autorisé).
   - Mais vous ne pouvez pas accéder aux comptes d'autres utilisateurs, ni gérer les options administratives (interdit).

Les tokens comme les JWT ont été créés pour répondre à plusieurs besoins techniques :
- **Authentification sans état :** Les serveurs n’ont pas besoin de sauvegarder l’état utilisateur, les informations nécessaires sont incluses dans le token.
- **Interopérabilité :** Les tokens peuvent être échangés entre différents systèmes ou parties d’un système distribué.
- **Sécurité :** Une signature permet de vérifier l’intégrité des données du token et s’assurer qu'elles n’ont pas été altérées.
- **Flexibilité :** Maintenus légers, les tokens fonctionnent sur une variété de protocoles (HTTP, websockets, etc.), contrairement aux sessions basées sur des cookies.

- Le **RGPD (Règlement Général sur la Protection des Données)** et les lois relatives au traçage des cookies visent à protéger la vie privée des utilisateurs. Ces réglementations concernent la collecte, le stockage et l'utilisation des données personnelles, en particulier pour des finalités publicitaires.
## 2. Les cookies 
Il existe plusieurs types de cookies
- **Session Cookie** : Expire à la fermeture du navigateur.
- **Persistent Cookie** : Stocké pour une durée définie.
- **Secure Cookie** : Accessible uniquement via HTTPS.
- **HttpOnly Cookie** : Non accessible par JavaScript (protège contre les attaques XSS).

Les **tokens** ne remplacent ni ne suppriment l’utilisation des cookies :
- Ils peuvent être **utilisés conjointement avec les cookies** (par exemple, un JWT peut être stocké dans un *cookie* ou dans le stockage local du navigateur).
- Cependant, si un **JWT contient des données personnelles identifiables**, son utilisation doit respecter le RGPD, notamment en ce qui concerne la sécurité, la durée de conservation, et la nécessité du consentement utilisateur.
`HttpOnly` est un attribut de sécurité des cookies qui empêche leur accès via JavaScript côté client. Lorsqu'un cookie est configuré avec l'attribut `HttpOnly`, il devient inaccessible avec des méthodes de manipulation JavaScript telles que `document.cookie`. Cela renforce la protection contre des attaques Cross-Site Scripting (XSS).

### Types de tokens
### Fonctionnement

Il existe plusieurs types de tokens, chacun ayant une utilisation spécifique.
```sequenceDiagram
    Serveur->>Client: Envoie un cookie via l'en-tête Set-Cookie
    Client->>Client: Stocke le cookie
    Client->>Serveur: Renvoie automatiquement le cookie à chaque requête
    Serveur->>Serveur: Utilise les informations du cookie pour identifier l'utilisateur
```
**Exemples d'utilisation :**

Dans un **JWT (JSON Web Token)**, le token est constitué de trois parties distinctes, séparées par des points (`.`) :
Stockage d'un jeton de session dans un cookie
```javascript
document.cookie = "session_id=abcdef123456; Secure; HttpOnly";
```

Récupération d'un cookie via JavaScript
```javascript
console.log(document.cookie); //sauf HttpOnly
```

## 3. Faut-il choisir un cookie ou un token ?!
Les **Tokens** sont recommandés pour les applications modernes (Single Page Apps, API REST, microservices). Les **Cookies** sont pratiques pour les sessions classiques, mais nécessitent des protections contre les CSRF. En général, on **combine des deux** en utilisant des tokens stockés dans des cookies sécurisés (`HttpOnly`, `Secure`).

**Bonnes pratiques de sécurité** :
Vu que ces chaînes de caractères sont utilisées pour authentifier, il faut :
- Toujours utiliser **HTTPS**.
- Protéger les tokens avec une expiration courte et un refresh token sécurisé.
- Utiliser `HttpOnly` et `Secure` pour les cookies.
- Implémenter des mécanismes de protection contre XSS et CSRF.

1. **Header** : Première partie avant le premier point.
2. **Payload** : Deuxième partie entre le premier et le deuxième point.
3. **Signature** : Troisième partie après le deuxième point.
**Exemple d'utilisation**

Voici un découpage de votre exemple de token :
Un site web avec un back-end peut stocker un **token JWT dans un cookie HttpOnly** pour sécuriser les sessions tout en utilisant les avantages des tokens.


## 4. Les différents types de tokens

### **4.1. Access Token (Token d'accès)**
Un **access token** est un jeton temporaire qui permet à une application (client) d'accéder aux ressources protégées d'un utilisateur.

#### **Caractéristiques principales** :
- Fourni par un **serveur d'autorisation** après une authentification réussie.
- A une durée de vie limitée (expire après un certain temps).
- Contient des informations telles que : 
  - Les permissions de l'utilisateur (scopes).
  - La durée de validité.
  - Le sujet auquel il se rapporte (par ex. : l'utilisateur).
- Doit être transmis par le client dans les requêtes (souvent dans des en-têtes HTTP).

#### **Exemple** :
1. Lorsqu'une application web veut accéder aux informations utilisateur via l'API Google, elle envoie un access token dans l'en-tête HTTP :
   ```http
   GET /calendar/v3/users/me/calendarList HTTP/1.1
   Authorization: Bearer ya29.a0Aa4xr...
   ```
2. Si le token est valide, Google répond avec la liste des calendriers de l'utilisateur.


### **4.4. Refresh Token (Token de rafraîchissement)**
Un **refresh token** est utilisé pour obtenir un **nouvel access token** sans nécessiter une nouvelle authentification de l'utilisateur.

#### **Caractéristiques principales** :
- A une durée de vie plus longue que l'access token (parfois plusieurs jours ou semaines).
- Est généralement stocké de manière sécurisée par le client.
- Ne doit jamais être partagé publiquement ou stocké dans des endroits non sécurisés.

#### **Exemple** :
Un utilisateur accède régulièrement à une application mobile, mais l'access token expire après 30 minutes.  
Pour éviter de redemander les identifiants à l'utilisateur, l'application utilise le refresh token pour en obtenir un nouveau en appelant l'endpoint :
   ```http
   POST /oauth2/token HTTP/1.1
   Content-Type: application/x-www-form-urlencoded

   grant_type=refresh_token&refresh_token=1//04vLbX1H...
   ```
Le serveur répond avec un nouvel access token valide.


### **4.3. ID Token**
Un **ID token** est utilisé pour **identifier un utilisateur**. Il ne donne pas accès à des ressources mais est souvent utilisé pour des mécanismes d'authentification, comme dans OpenID Connect.

#### **Caractéristiques principales** :
- Contient des informations sur l'utilisateur, codées généralement sous forme JWT (JSON Web Token).
- Informations typiques : identifiant unique de l'utilisateur (`sub`), nom, email, etc.
- Strictement destiné à l'authentification.

#### **Exemple 1** :
Lors de la connexion via un tiers (comme Google), l'ID token contient des informations sur l'utilisateur :
   ```json
   {
     "iss": "https://accounts.google.com",
     "sub": "1234567890",
     "email": "user@example.com",
     "name": "John Doe",
     "exp": 1693046400
   }
   ```

#### **Exemple 2** :
Un **JWT (JSON Web Token)** est constitué de trois parties distinctes, séparées par des points (`.`) :

  ```javascript
  eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImpvaG4iLCJleHAiOjE2NzAwMjYyMDB9._kC7j_A1Kfw
  ```

- **Header** (première partie jusqu'au premier `.`) :  `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9`
-  **Payload** (deuxième partie entre les deux `.`) : `eyJ1c2VybmFtZSI6ImpvaG4iLCJleHAiOjE2NzAwMjYyMDB9`
- **Signature** (troisième partie après le dernier `.`) : `_kC7j_A1Kfw`

- Les **OAuth Access Tokens** sont des jetons d’accès utilisés dans le cadre du protocole OAuth 2.0, qui permet l’authentification et l’autorisation d’accès aux ressources d’un utilisateur sans exposer ses identifiants. Ces tokens sont généralement envoyés dans l’en-tête HTTP `Authorization: Bearer <token>`, comme dans cet exemple :

```javascript
fetch('https://api.example.com/protected', {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer <your_access_token>'
  }
})
.then(response => response.json())
.then(data => console.log(data));
```
### **4.4. Bearer Token (Token porteur)**
Un **bearer token**, type courant d'access token, est utilisé pour accorder un accès direct. Celui qui possède ce token peut accéder à la ressource.

Ils expirent généralement après une courte durée et nécessitent un **Refresh Token** pour renouveler l'accès sans forcer l'utilisateur à se reconnecter.
#### **Caractéristiques principales** :
- Inclus dans l'en-tête HTTP `Authorization` lors de l'envoi d'une requête.
- Considéré comme une "clé d'accès" : en cas de compromission, il peut être utilisé par une tierce partie.

Le **Refresh Token** est un token spécial permettant d'obtenir un nouveau token d'accès sans nécessiter une ré-authentification complète. Contrairement aux tokens d'accès, il est conçu pour être stocké de manière sécurisée, comme dans un cookie HttpOnly ou une base de données.
#### **Exemple** :
Une requête REST utilisant un bearer token dans l'en-tête :
   ```http
   GET /api/v2/user/profile HTTP/1.1
   Authorization: Bearer abc123xyz456
   ```
Si le token est valide, le serveur renvoie les informations de profil utilisateur.


Les **CSRF Tokens (Cross-Site Request Forgery Tokens)** sont utilisés pour protéger les applications web contre les attaques CSRF, qui exploitent la confiance d’un site web envers un utilisateur authentifié. Un token CSRF est généré côté serveur et inséré dans un champ caché d’un formulaire. Lorsque l’utilisateur soumet le formulaire, le serveur vérifie la validité du token avant de traiter la requête. Voici un exemple d’implémentation :
### **4.5. CSRF Token (Token contre les attaques CSRF)**
Un **CSRF token** (Cross-Site Request Forgery token) est généré pour aider à sécuriser les requêtes des utilisateurs contre les attaques CSRF.

```
<form method="POST" action="/submit">
  <input type="hidden" name="csrf_token" value="abcdef123456" />
  <input type="text" name="username" />
  <button type="submit">Envoyer</button>
#### **Caractéristiques principales** :
- Inclus dans les formulaires HTML sous un champ caché ou dans les requêtes POST.
- Permet au serveur de vérifier que la requête provient d'une source fiable.

#### **Exemple** :
Un serveur génère le champ `csrf_token` dans un formulaire :
   ```html
   <form action="/submit" method="POST">
     <input type="hidden" name="csrf_token" value="aBc123dEf456">
     <input type="text" name="name" placeholder="Name">
     <button type="submit">Submit</button>
   </form>
   ```
Ce mécanisme empêche les attaques où un utilisateur connecté pourrait être forcé à exécuter une action malveillante à son insu.
Lorsqu'une attaque tente d'envoyer une requête malveillante sans ce token, la requête est rejetée.

Les **API Tokens** sont des clés secrètes utilisées pour sécuriser l'accès aux API. Contrairement aux tokens OAuth, ils ne sont pas toujours liés à un utilisateur spécifique mais plutôt à une application ou un service. Ils permettent d’authentifier les requêtes sans nécessiter une session utilisateur. Un exemple d'utilisation serait l'ajout d’un token dans une requête API :
```javascript
fetch('https://api.example.com/data', {
  method: 'GET',
  headers: {
    'Authorization': 'Token abcdef123456'
  }
})
.then(response => response.json())
.then(data => console.log(data));
### **4.6. API Key (Clé API)**
L'**API Key** est une clé unique générée pour identifier et authentifier une application appelant une API.

#### **Caractéristiques principales** :
- Fournit un accès basique à des ressources ou services.
- Simple à configurer mais moins sécurisée (pas de gestion avancée des permissions ou expiration automatique).

#### **Exemple** :
Lorsqu'un développeur utilise l'API Google Maps, il doit inclure sa clé API dans les requêtes :
   ```http
   GET https://maps.googleapis.com/maps/api/geocode/json?address=Paris&key=AIzaSyDxxx
   ```
Ces tokens doivent être stockés de manière sécurisée et régénérés régulièrement pour éviter tout risque de compromission.
Si la clé est valide, l'API retourne les coordonnées géographiques pour "Paris".


## 2. Qu'est-ce qu'un Cookie ?
Un **cookie** est un petit fichier stocké dans le navigateur contenant des données utilisées par un site web.
### **Stockage des tokens coté client**

### Types de cookies
- **Session Cookie** : Expire à la fermeture du navigateur.
- **Persistent Cookie** : Stocké pour une durée définie.
- **Secure Cookie** : Accessible uniquement via HTTPS.
- **HttpOnly Cookie** : Non accessible par JavaScript (protège contre les attaques XSS).
Le stockage des tokens côté client représente un défi important pour équilibrer **sécurité** et **utilisabilité**. Les tokens sont utilisés pour authentifier ou autoriser un utilisateur, et doivent donc être protégés contre les attaques courantes, comme le **Cross-Site Scripting (XSS)** ou le **Cross-Site Request Forgery (CSRF)**. Voici les principales options disponibles pour stocker des tokens sur le client, avec leurs avantages et inconvénients.

### Fonctionnement
1. Le serveur envoie un cookie au client via l'en-tête `Set-Cookie`.
2. Le navigateur stocke le cookie.
3. À chaque requête suivante, le navigateur renvoie automatiquement le cookie au serveur.
4. Le serveur utilise les informations du cookie pour identifier l'utilisateur.
#### **Stockage local (Local Storage)**

### Exemples d'utilisation
#### 1. Stockage d'un jeton de session dans un cookie
```javascript
document.cookie = "session_id=abcdef123456; Secure; HttpOnly";
```
Le stockage local (`localStorage`) est une méthode courante, accessible via JavaScript, qui consiste à enregistrer des paires clé-valeur dans le navigateur. Il a l'avantage de conserver les données de manière persistante, même après la fermeture du navigateur ou le rechargement de la page.

#### 2. Récupération d'un cookie via JavaScript (si non HttpOnly)
```javascript
console.log(document.cookie);
```
Cependant, le local storage est **vulnérable aux attaques XSS**. Si un attaquant parvient à injecter du code malveillant sur votre application web, il pourrait facilement accéder au contenu du local storage, y compris aux tokens stockés. Cela pose un réel problème pour le stockage des **access tokens** ou **refresh tokens**, car cela compromettrait l'utilisateur.

En résumé, **il est déconseillé** d'utiliser le local storage pour des tokens sensibles. Il pourrait convenir pour des données non critiques ou comme solution temporaire.

## 3. Différences entre Tokens et Cookies
| Critère            | Tokens (JWT, OAuth, CSRF)      | Cookies                 |
|--------------------|------------------------|-------------------------|
| Stockage         | Local Storage, Memory   | Navigateur (via HTTP)   |
| Transmission      | Manuel (`Authorization` header) | Automatique (`Set-Cookie`) |
| Sécurité         | Peut être intercepté si mal protégé | Vulnérable aux attaques CSRF |
| Expiration       | Défini par l'émetteur   | Dépend de la configuration |
| Utilisation      | API REST, Single Page Apps, Protection CSRF | Sessions classiques |
| Dépendance au serveur | Stateless | Stateful |
#### **Stockage temporaire avec Session Storage**

---
Semblable au local storage, le `sessionStorage` permet d'enregistrer des paires clé-valeur dans le navigateur, mais avec une différence notable : les données sont supprimées dès que l'onglet ou la fenêtre est fermée. Cela le rend plus adapté pour des tokens qui ne doivent être accessibles que temporairement.

## 4. Faut-il choisir un cookie ou un token ?!
Les **Tokens** sont recommandés pour les applications modernes (Single Page Apps, API REST, microservices). Les **Cookies** : Pratiques pour les sessions classiques, mais nécessitent des protections contre CSRF.
- **Combinaison des deux** : Utiliser des tokens stockés dans des cookies sécurisés (`HttpOnly`, `Secure`).
L'inconvénient principal reste similaire à celui du local storage : il est également vulnérable aux attaques XSS. Cela signifie que, bien que les chaînes ne soient pas persistantes, si une injection malveillante se produit dans la session actuelle, les données du session storage peuvent être compromises.

À ce titre, le session storage peut être utilisé pour des **tokens de courte durée** dans des scénarios où la sécurité est moins critique.

#### **Stockage sécurisé avec HTTP Cookies**

Les **cookies** offrent une méthode efficace pour stocker des tokens de manière sécurisée, à condition qu'ils soient correctement configurés. Avec des options comme `HttpOnly`, un cookie devient inaccessible directement via JavaScript, ce qui le protège contre les attaques XSS. De plus, utiliser l'attribut `Secure` garantit que le cookie sera transmis uniquement via des connexions HTTPS.

Un autre avantage majeur d'utiliser les cookies réside dans leur intégration naturelle avec les navigateurs. Les cookies peuvent être automatiquement inclus dans chaque requête HTTP envoyée à un serveur, ce qui simplifie la gestion des sessions et de l'authentification. Cependant, cela peut entraîner une augmentation du trafic réseau si le cookie est volumineux et qu'il est envoyé sur chaque requête.

Enfin, pour limiter les risques d'attaques CSRF, il est fortement recommandé d'activer l'attribut `SameSite`, avec une préférence pour la stricte (`Strict`).

En conclusion, les cookies sont **fortement recommandés** pour stocker des access tokens ou refresh tokens sensibles, en particulier pour les applications web utilisant des mécanismes basés sur les sessions.

#### **Stockage en mémoire (In-Memory)**

Une autre méthode consiste à stocker les tokens directement dans la mémoire vive de l'application, par exemple dans une variable JavaScript. Cela garantit que les tokens ne seront pas persistés entre les sessions ou dans des emplacements facilement accessibles (comme le DOM). Ainsi, c'est une solution très **sécurisée contre les attaques XSS**.

Cependant, cette approche présente une limitation : si l'utilisateur actualise la page ou ferme puis rouvre un onglet, le token sera perdu, car il n'est pas stocké de manière persistante. Cette méthode est donc idéale pour les applications **SPA (Single Page Applications)** où il est acceptable que le token ne survive qu'à la durée de vie de la session en cours.

En résumé, le stockage en mémoire est une option simple et **sécurisée** pour limiter drastiquement la surface d'attaque, mais elle ne convient pas dans les cas où la persistance est nécessaire.

#### **Stockage avancé avec IndexDB ou Web SQL**

Pour les applications qui nécessitent un stockage local structuré et résilient, **IndexDB** ou **Web SQL** peuvent être de bonnes alternatives. Ces technologies permettent de stocker les tokens dans une base de données locale, avec plus de flexibilité et de capacités que le local storage ou le session storage.

Cependant, bien que les données soient isolées par le principe de **Same-Origin Policy**, elles restent accessibles au client via JavaScript, et sont donc exposées à des attaques XSS comme les autres options de stockage côté client. Par exemple, sans chiffrement supplémentaire, un attaquant pourrait lire et voler ces données si une vulnérabilité XSS existe sur l'application.

Cette approche peut être intéressante pour des applications complexes nécessitant une gestion locale des tokens, mais elle n'est pas idéale pour des informations sensibles comme des access tokens, à moins que des protections supplémentaires, comme **le chiffrement**, soient mises en place.


#### **Recommandations générales**

- **Privilégiez HTTP Cookies** si vos tokens sont sensibles. Assurez-vous de configurer les attributs de sécurité (`HttpOnly`, `Secure`, `SameSite`) pour les protéger.
- **Protégez votre application contre les attaques XSS** en appliquant des politiques strictes, comme les **Content Security Policy (CSP)**.
- Si vous optez pour une SPA (Single Page Application), combinez un **stockage en mémoire** avec un mécanisme de sécurité qui réduit le risque (exemple : Proxy server pour éviter la gestion directe des tokens côté client).
- Pour des tokens de courte durée ou à faible impact, **session storage** peut suffire, mais restez vigilant.



### **Les tokens et la loi (RGPD)**

Les tokens comme les JWT ont été créés pour répondre à plusieurs besoins techniques :
- **Authentification sans état :** Les serveurs n'ont pas besoin de sauvegarder l'état utilisateur, les informations nécessaires sont incluses dans le token.
- **Interopérabilité :** Les tokens peuvent être échangés entre différents systèmes ou parties d'un système distribué.
- **Sécurité :** Une signature permet de vérifier l'intégrité des données du token et s'assurer qu'elles n'ont pas été altérées.
- **Flexibilité :** Maintenus légers, les tokens fonctionnent sur une variété de protocoles (HTTP, websockets, etc.), contrairement aux sessions basées sur des cookies.

- Le **RGPD (Règlement Général sur la Protection des Données)** et les lois relatives au traçage des cookies visent à protéger la vie privée des utilisateurs. Ces réglementations concernent la collecte, le stockage et l'utilisation des données personnelles, en particulier pour des finalités publicitaires.

Les **tokens** ne remplacent ni ne suppriment l'utilisation des cookies :
- Ils peuvent être **utilisés conjointement avec les cookies** (par exemple, un JWT peut être stocké dans un *cookie* ou dans le stockage local du navigateur).
- Cependant, si un **JWT contient des données personnelles identifiables**, son utilisation doit respecter le RGPD, notamment en ce qui concerne la sécurité, la durée de conservation, et la nécessité du consentement utilisateur.

🔹 **Bonnes pratiques de sécurité** :
- Toujours utiliser **HTTPS**.
- Protéger les tokens avec une expiration courte et un refresh token sécurisé.
- Utiliser `HttpOnly` et `Secure` pour les cookies.
- Implémenter des mécanismes de protection contre XSS et CSRF.
💡 **Exemple d'utilisation** :
- Un site web avec un back-end peut stocker un **token JWT dans un cookie HttpOnly** pour sécuriser les sessions tout en utilisant les avantages des tokens.