Translated ['src/network-services-pentesting/pentesting-web/graphql.md']

This commit is contained in:
Translator 2025-01-22 23:13:02 +00:00
parent be9ed6b4cf
commit 148151dd10

View File

@ -170,7 +170,7 @@ Si l'introspection est activée, vous pouvez utiliser [**GraphQL Voyager**](http
### Interrogation
Maintenant que nous savons quel type d'informations est enregistré dans la base de données, essayons d'**extraire quelques valeurs**.
Maintenant que nous savons quel type d'information est enregistré dans la base de données, essayons d'**extraire quelques valeurs**.
Dans l'introspection, vous pouvez trouver **quel objet vous pouvez interroger directement** (car vous ne pouvez pas interroger un objet juste parce qu'il existe). Dans l'image suivante, vous pouvez voir que le "_queryType_" s'appelle "_Query_" et qu'un des champs de l'objet "_Query_" est "_flags_", qui est également un type d'objet. Par conséquent, vous pouvez interroger l'objet flag.
@ -202,7 +202,7 @@ Cependant, dans cet exemple, si vous essayez de le faire, vous obtenez cette **e
![](<../../images/image (1042).png>)
On dirait que d'une manière ou d'une autre, il va rechercher en utilisant l'argument "_**uid**_" de type _**Int**_.\
Quoi qu'il en soit, nous le savions déjà, dans la section [Basic Enumeration](graphql.md#basic-enumeration), une requête a été proposée qui nous montrait toutes les informations nécessaires : `query={__schema{types{name,fields{name, args{name,description,type{name, kind, ofType{name, kind}}}}}}}`
Quoi qu'il en soit, nous savions déjà cela, dans la section [Basic Enumeration](graphql.md#basic-enumeration), une requête a été proposée qui nous montrait toutes les informations nécessaires : `query={__schema{types{name,fields{name, args{name,description,type{name, kind, ofType{name, kind}}}}}}}`
Si vous lisez l'image fournie lorsque j'exécute cette requête, vous verrez que "_**user**_" avait l'**arg** "_**uid**_" de type _Int_.
@ -219,7 +219,7 @@ Et pendant la **phase d'énumération**, j'ai découvert que l'objet "_**dbuser*
**Truc de dump de chaîne de requête (merci à @BinaryShadow\_)**
Si vous pouvez rechercher par un type de chaîne, comme : `query={theusers(description: ""){username,password}}` et que vous **cherchez une chaîne vide**, cela va **dump toutes les données**. (_Notez que cet exemple n'est pas lié à l'exemple des tutoriels, pour cet exemple, supposons que vous pouvez rechercher en utilisant "**theusers**" par un champ de chaîne appelé "**description**"_).
Si vous pouvez rechercher par un type de chaîne, comme : `query={theusers(description: ""){username,password}}` et que vous **cherchez une chaîne vide**, cela va **dump toutes les données**. (_Notez que cet exemple n'est pas lié à l'exemple des tutoriels, pour cet exemple, supposez que vous pouvez rechercher en utilisant "**theusers**" par un champ de chaîne appelé "**description**"_).
### Recherche
@ -332,14 +332,14 @@ releaseYear
}
}
```
### Surcharge de Directive
### Surcharge de directive
Comme expliqué dans [**l'une des vulnérabilités décrites dans ce rapport**](https://www.landh.tech/blog/20240304-google-hack-50000/), une surcharge de directive implique d'appeler une directive même des millions de fois pour faire perdre des opérations au serveur jusqu'à ce qu'il soit possible de le DoS.
### Batching brute-force dans 1 requête API
Cette information a été tirée de [https://lab.wallarm.com/graphql-batching-attack/](https://lab.wallarm.com/graphql-batching-attack/).\
Authentification via l'API GraphQL avec **l'envoi simultané de nombreuses requêtes avec différentes identifiants** pour le vérifier. C'est une attaque par force brute classique, mais il est maintenant possible d'envoyer plus d'une paire login/mot de passe par requête HTTP grâce à la fonctionnalité de batching de GraphQL. Cette approche tromperait les applications externes de surveillance de taux en leur faisant croire que tout va bien et qu'il n'y a pas de bot de force brute essayant de deviner des mots de passe.
Authentification via l'API GraphQL avec **l'envoi simultané de nombreuses requêtes avec différentes identifiants** pour le vérifier. C'est une attaque par force brute classique, mais il est maintenant possible d'envoyer plus d'une paire login/mot de passe par requête HTTP grâce à la fonctionnalité de batching de GraphQL. Cette approche tromperait les applications externes de surveillance des taux en leur faisant croire que tout va bien et qu'il n'y a pas de bot de force brute essayant de deviner des mots de passe.
Vous pouvez trouver ci-dessous la démonstration la plus simple d'une requête d'authentification d'application, avec **3 paires email/mot de passe différentes à la fois**. Évidemment, il est possible d'en envoyer des milliers dans une seule requête de la même manière :
@ -353,13 +353,13 @@ Comme nous pouvons le voir sur la capture d'écran de la réponse, les première
De plus en plus de **points de terminaison graphql désactivent l'introspection**. Cependant, les erreurs que graphql renvoie lorsqu'une requête inattendue est reçue sont suffisantes pour que des outils comme [**clairvoyance**](https://github.com/nikitastupin/clairvoyance) puissent recréer la plupart du schéma.
De plus, l'extension Burp Suite [**GraphQuail**](https://github.com/forcesunseen/graphquail) **observe les requêtes API GraphQL passant par Burp** et **construit** un **schéma** GraphQL interne avec chaque nouvelle requête qu'il voit. Elle peut également exposer le schéma pour GraphiQL et Voyager. L'extension renvoie une réponse factice lorsqu'elle reçoit une requête d'introspection. En conséquence, GraphQuail montre toutes les requêtes, arguments et champs disponibles pour une utilisation au sein de l'API. Pour plus d'infos [**vérifiez ceci**](https://blog.forcesunseen.com/graphql-security-testing-without-a-schema).
De plus, l'extension Burp Suite [**GraphQuail**](https://github.com/forcesunseen/graphquail) **observe les requêtes API GraphQL passant par Burp** et **construit** un **schéma** GraphQL interne avec chaque nouvelle requête qu'il voit. Il peut également exposer le schéma pour GraphiQL et Voyager. L'extension renvoie une réponse factice lorsqu'elle reçoit une requête d'introspection. En conséquence, GraphQuail montre toutes les requêtes, arguments et champs disponibles pour une utilisation au sein de l'API. Pour plus d'infos [**vérifiez ceci**](https://blog.forcesunseen.com/graphql-security-testing-without-a-schema).
Une belle **liste de mots** pour découvrir [**les entités GraphQL peut être trouvée ici**](https://github.com/Escape-Technologies/graphql-wordlist?).
### Contournement des défenses d'introspection GraphQL <a href="#bypassing-graphql-introspection-defences" id="bypassing-graphql-introspection-defences"></a>
Pour contourner les restrictions sur les requêtes d'introspection dans les API, l'insertion d'un **caractère spécial après le mot-clé `__schema`** s'avère efficace. Cette méthode exploite les erreurs courantes des développeurs dans les motifs regex qui visent à bloquer l'introspection en se concentrant sur le mot-clé `__schema`. En ajoutant des caractères comme **espaces, nouvelles lignes et virgules**, que GraphQL ignore mais qui pourraient ne pas être pris en compte dans les regex, les restrictions peuvent être contournées. Par exemple, une requête d'introspection avec une nouvelle ligne après `__schema` peut contourner de telles défenses :
Pour contourner les restrictions sur les requêtes d'introspection dans les API, l'insertion d'un **caractère spécial après le mot-clé `__schema`** s'avère efficace. Cette méthode exploite les erreurs courantes des développeurs dans les motifs regex qui visent à bloquer l'introspection en se concentrant sur le mot-clé `__schema`. En ajoutant des caractères comme **espaces, nouvelles lignes et virgules**, que GraphQL ignore mais qui pourraient ne pas être pris en compte dans le regex, les restrictions peuvent être contournées. Par exemple, une requête d'introspection avec une nouvelle ligne après `__schema` peut contourner de telles défenses :
```bash
# Example with newline to bypass
{
@ -369,7 +369,7 @@ Pour contourner les restrictions sur les requêtes d'introspection dans les API,
```
Si cela échoue, envisagez des méthodes de requête alternatives, telles que **GET requests** ou **POST avec `x-www-form-urlencoded`**, car des restrictions peuvent ne s'appliquer qu'aux requêtes POST.
### Essayez WebSockets
### Essayez les WebSockets
Comme mentionné dans [**cette conférence**](https://www.youtube.com/watch?v=tIo_t5uUK50), vérifiez s'il est possible de se connecter à graphQL via WebSockets, car cela pourrait vous permettre de contourner un éventuel WAF et de faire en sorte que la communication WebSocket divulgue le schéma de graphQL :
```javascript
@ -411,17 +411,17 @@ Si vous ne savez pas ce qu'est le CSRF, lisez la page suivante :
../../pentesting-web/csrf-cross-site-request-forgery.md
{{#endref}}
Vous pourrez trouver plusieurs points de terminaison GraphQL **configurés sans tokens CSRF.**
Là-bas, vous pourrez trouver plusieurs points de terminaison GraphQL **configurés sans jetons CSRF.**
Notez que les requêtes GraphQL sont généralement envoyées via des requêtes POST utilisant le Content-Type **`application/json`**.
Notez que les requêtes GraphQL sont généralement envoyées via des requêtes POST utilisant le type de contenu **`application/json`**.
```javascript
{"operationName":null,"variables":{},"query":"{\n user {\n firstName\n __typename\n }\n}\n"}
```
Cependant, la plupart des points de terminaison GraphQL prennent également en charge les **`form-urlencoded` POST requests :**
Cependant, la plupart des points de terminaison GraphQL prennent également en charge les requêtes POST **`form-urlencoded` :**
```javascript
query=%7B%0A++user+%7B%0A++++firstName%0A++++__typename%0A++%7D%0A%7D%0A
```
Par conséquent, comme les requêtes CSRF comme celles précédentes sont envoyées **sans requêtes préalables**, il est possible de **faire** **des modifications** dans le GraphQL en abusant d'un CSRF.
Par conséquent, comme les requêtes CSRF comme celles précédentes sont envoyées **sans requêtes préalables**, il est possible de **faire** **des changements** dans le GraphQL en abusant d'un CSRF.
Cependant, notez que la nouvelle valeur par défaut du cookie du drapeau `samesite` de Chrome est `Lax`. Cela signifie que le cookie ne sera envoyé que depuis un site tiers dans les requêtes GET.
@ -465,13 +465,13 @@ Dans l'exemple ci-dessous, vous pouvez voir que l'opération est "forgotPassword
## Contournement des limites de taux en utilisant des alias dans GraphQL
Dans GraphQL, les alias sont une fonctionnalité puissante qui permet de **nommer explicitement les propriétés** lors d'une demande d'API. Cette capacité est particulièrement utile pour récupérer **plusieurs instances du même type** d'objet dans une seule demande. Les alias peuvent être utilisés pour surmonter la limitation qui empêche les objets GraphQL d'avoir plusieurs propriétés avec le même nom.
Dans GraphQL, les alias sont une fonctionnalité puissante qui permet de **nommer explicitement les propriétés** lors d'une requête API. Cette capacité est particulièrement utile pour récupérer **plusieurs instances du même type** d'objet dans une seule requête. Les alias peuvent être utilisés pour surmonter la limitation qui empêche les objets GraphQL d'avoir plusieurs propriétés avec le même nom.
Pour une compréhension détaillée des alias GraphQL, la ressource suivante est recommandée : [Aliases](https://portswigger.net/web-security/graphql/what-is-graphql#aliases).
Bien que le but principal des alias soit de réduire la nécessité de nombreux appels API, un cas d'utilisation non intentionnel a été identifié où les alias peuvent être exploités pour exécuter des attaques par force brute sur un point de terminaison GraphQL. Cela est possible car certains points de terminaison sont protégés par des limiteurs de taux conçus pour contrer les attaques par force brute en restreignant le **nombre de requêtes HTTP**. Cependant, ces limiteurs de taux pourraient ne pas tenir compte du nombre d'opérations dans chaque demande. Étant donné que les alias permettent l'inclusion de plusieurs requêtes dans une seule demande HTTP, ils peuvent contourner de telles mesures de limitation de taux.
Bien que le but principal des alias soit de réduire la nécessité de nombreux appels API, un cas d'utilisation non intentionnel a été identifié où les alias peuvent être exploités pour exécuter des attaques par force brute sur un point de terminaison GraphQL. Cela est possible car certains points de terminaison sont protégés par des limiteurs de taux conçus pour contrer les attaques par force brute en restreignant le **nombre de requêtes HTTP**. Cependant, ces limiteurs de taux pourraient ne pas tenir compte du nombre d'opérations dans chaque requête. Étant donné que les alias permettent d'inclure plusieurs requêtes dans une seule requête HTTP, ils peuvent contourner de telles mesures de limitation de taux.
Considérez l'exemple fourni ci-dessous, qui illustre comment des requêtes aliasées peuvent être utilisées pour vérifier la validité des codes de réduction en magasin. Cette méthode pourrait contourner la limitation de taux puisqu'elle compile plusieurs requêtes en une seule demande HTTP, permettant potentiellement la vérification de nombreux codes de réduction simultanément.
Considérez l'exemple fourni ci-dessous, qui illustre comment des requêtes aliasées peuvent être utilisées pour vérifier la validité des codes de réduction en magasin. Cette méthode pourrait contourner la limitation de taux puisqu'elle compile plusieurs requêtes en une seule requête HTTP, permettant potentiellement la vérification de plusieurs codes de réduction simultanément.
```bash
# Example of a request utilizing aliased queries to check for valid discount codes
query isValidDiscount($code: Int) {
@ -501,7 +501,7 @@ Pour atténuer cela, mettez en œuvre des limites de compte d'alias, une analyse
### **Batching de Requêtes Basé sur des Tableaux**
Le **Batching de Requêtes Basé sur des Tableaux** est une vulnérabilité où une API GraphQL permet de regrouper plusieurs requêtes dans une seule demande, permettant à un attaquant d'envoyer un grand nombre de requêtes simultanément. Cela peut submerger le backend en exécutant toutes les requêtes groupées en parallèle, consommant des ressources excessives (CPU, mémoire, connexions à la base de données) et pouvant potentiellement conduire à un **Denial of Service (DoS)**. S'il n'existe aucune limite sur le nombre de requêtes dans un lot, un attaquant peut exploiter cela pour dégrader la disponibilité du service.
**Batching de Requêtes Basé sur des Tableaux** est une vulnérabilité où une API GraphQL permet de regrouper plusieurs requêtes dans une seule demande, permettant à un attaquant d'envoyer un grand nombre de requêtes simultanément. Cela peut submerger le backend en exécutant toutes les requêtes groupées en parallèle, consommant des ressources excessives (CPU, mémoire, connexions à la base de données) et pouvant potentiellement conduire à un **Denial of Service (DoS)**. S'il n'existe aucune limite sur le nombre de requêtes dans un lot, un attaquant peut exploiter cela pour dégrader la disponibilité du service.
```graphql
# Test provided by https://github.com/dolevf/graphql-cop
curl -X POST -H "User-Agent: graphql-cop/1.13" \
@ -553,7 +553,7 @@ curl -X POST -H "User-Agent: graphql-cop/1.13" -H "Content-Type: application/jso
- [https://github.com/dolevf/graphql-cop](https://github.com/dolevf/graphql-cop) : Tester les erreurs de configuration courantes des points de terminaison graphql
- [https://github.com/assetnote/batchql](https://github.com/assetnote/batchql) : Script d'audit de sécurité GraphQL axé sur l'exécution de requêtes et de mutations GraphQL en lot.
- [https://github.com/dolevf/graphw00f](https://github.com/dolevf/graphw00f) : Identifier le graphql utilisé
- [https://github.com/gsmith257-cyber/GraphCrawler](https://github.com/gsmith257-cyber/GraphCrawler) : Boîte à outils pouvant être utilisée pour récupérer des schémas et rechercher des données sensibles, tester l'autorisation, forcer les schémas et trouver des chemins vers un type donné.
- [https://github.com/gsmith257-cyber/GraphCrawler](https://github.com/gsmith257-cyber/GraphCrawler) : Boîte à outils pouvant être utilisée pour récupérer des schémas et rechercher des données sensibles, tester l'autorisation, forcer les schémas par brute force et trouver des chemins vers un type donné.
- [https://blog.doyensec.com/2020/03/26/graphql-scanner.html](https://blog.doyensec.com/2020/03/26/graphql-scanner.html) : Peut être utilisé comme autonome ou [extension Burp](https://github.com/doyensec/inql).
- [https://github.com/swisskyrepo/GraphQLmap](https://github.com/swisskyrepo/GraphQLmap) : Peut également être utilisé comme client CLI pour automatiser les attaques
- [https://gitlab.com/dee-see/graphql-path-enum](https://gitlab.com/dee-see/graphql-path-enum) : Outil qui répertorie les différentes manières de **atteindre un type donné dans un schéma GraphQL**.