📶GraphQL
Graph Query Language
Dernière mise à jour
Graph Query Language
Dernière mise à jour
https://ivangoncharov.github.io/graphql-voyager/: Transforme les données graphql en graphique
https://lucasconstantino.github.io/graphiql-online/: Permet une interaction facilité avec les endpoints graphql.
https://altair-gql.sirmuel.design/: Même principe que graphiql.
https://github.com/nicholasaleks/graphql-threat-matrix: matrice des surfaces d'attaque de chaque implémentations de graphQL.
GraphQL fonctionne en un seul endpoint qui ne renvoie que les informations exactement demandées.
Cette technologie fonctionne avec deux types de requêtes:
Les queries sont utilisées afin de recupérer des données à l'aide d'opérations spécifiquement définies. Ils s'agit grossièrement de l'équivalent de la méthode GET du protocole HTTP pour l'API.
Pour que les queries renvoient les données voulues, il faut que les données demandées correspondent exactement à celles souhaités dans la réponse du serveur. Les requêtes peuvent demander des arguments et sur la base de ces arguments, des données spécifiques peuvent être interrogés.
Exemple:
Les mutations quant à elles sont utilisées pour ajouter, modifier ou supprimer des données dans le système. Il s'agit grossièrement de l'équivalent des méthodes PUT, DELETE et POST du protocole HTTP dans l'API. L'avantage de ce type de requêtes est qu'il est alors possible de demander à mettre à jour une donnée dans la même requête en changeant simplement le type de requête (query -> mutation).
Exemple:
L'introspection est une fonctionnalité du système pouvant permettre si il est activé d'interroger les ressources disponibles dans le schéma de l'API. De ce fait, il est possible de dumper entièrement le schéma de l'API en envoyant postant ces données depuis l'endpoint de l'API:
{"query": "query IntrospectionQuery{__schema{queryType{name}mutationType{name}subscriptionType{name}types{...FullType}directives{name description locations args{...InputValue}}}}fragment FullType on __Type{kind name description fields(includeDeprecated:true){name description args{...InputValue}type{...TypeRef}isDeprecated deprecationReason}inputFields{...InputValue}interfaces{...TypeRef}enumValues(includeDeprecated:true){name description isDeprecated deprecationReason}possibleTypes{...TypeRef}}fragment InputValue on __InputValue{name description type{...TypeRef}defaultValue}fragment TypeRef on __Type{kind name ofType{kind name ofType{kind name ofType{kind name ofType{kind name ofType{kind name ofType{kind name ofType{kind name}}}}}}}}" }
La taille de la réponse obtenue peut alors être très important rendant difficile le travail d'analyse mais heureusement il existe le site https://ivangoncharov.github.io/graphql-voyager/ permettant de convertir les données brutes obtenues en graphique plus lisible.
Dans le cas ou l'introspection serait désactivé, il est nécessaire de fuzz l'endpoint pour trouver des endpoints.
Les API graphql nécessites de procéder aux mêmes tests que pour une API REST par exemple à savoir le Top 10 OWASP et autres vulnérabilités WEB.
La Batching attack est une attaque spécifique aux API graphql, elle permet d'envoyer plusieurs demandes à un seul endpoint et en une seule requête et ceux sans risque d'être bloqué.
Il s'agit donc d'une attaque parfaite dans les scénarios de brute-force et de bypass de 2FA (elle permet principalement de bypass les méchanismes de rate-limit).
Trouver des cycles dans une introspection graphql:
$ inql -t https://chat-api.swapcard.com/graphql --generate-cycles -o cycles
la technique est simple, il s'agit de trouver un champs envoyant une très grande réponse et de dupliquer la demande plusieurs fois puis analyser le temps de réponse.
Exemple:
Il est possible d'utiliser l'overloading d'alias dans un but de dénis de service de la même manière que pour l'attaque précédente en trouvant un champs utilisant beaucoup de ressources et en la dupliquant avec des alias différents pour les considérés comme des requêtes différentes.
Exemple:
Il s'agit de la même chose qu'une duplication attack mais avec des directives de cette manière:
Les serveurs graphQL peuvent implémenter des limites sur la quantité de données qu'ils renvoient par défaut. Ceci est particulièrement important pour les champs qui renvoient des tableaux.
Si une requête peut utiliser un argument permettant de limiter le nombre de retours dans la réponse, (limit, offset, max...) on peut essayer d'entrer une très grande afin de forcer la base de donnée à renvoyer une quantité de données qui pourrait entraîner un DoS.
Via erreurs verbeuses / stack traces
Via entrées de contenu sensibles dans une requête GET
Via debug mode activé (/graphql?debug=1, /graphql?XDEBUG_SESSION_START=PHPSTORM)
Via fuites d'infos dans la console du navigateur
Privilégier les argument prenant des strings.
Automatisation avec sqlmap:
Dans la requête burp suite:
placer un asterisk (*) au point d'injection souhaité
Clic droit > "Copy to file"
$ sqlmap -r request.txt —dbms=sqlite —tables
Exmple avec Commix:
$ commix --url="https://target.com/graphql" --data='{"query":"query{exemple(arg:"test ")}"}' -p arg
CrackQL est un outil de brute-forcing et fuzzing de GraphQL.
Exemple d'utilisation:
$ python3 CrackQL.py -t http://target.com/graphql -q sample-queries/login.graphql -i sample-inputs/usernames_and_passwords.csv --verbose [-b pour utiliser du batching]
ressource: https://github.com/nicholasaleks/CrackQL
graphql-cop est un scanner de vulnérabilité dédié aux APIs GraphQL.
Utilisation:
ressource: https://github.com/dolevf/graphql-cop
BatchQL est un script d'audit de sécurité GraphQL axé sur l'exécution de requêtes et de mutations GraphQL par lots.
Utilisation:
ressource: https://github.com/assetnote/batchql
graphw00f est un scanner d'endpoint graphQL permettant de détecter le moteur graphql utilisé.
Utilisation:
ressource: https://github.com/dolevf/graphw00f
InQL est une extension de burp suite permettant d'arriver à un resultat semblable au site web "graphiql".
GraphQLmap est un outil permettant d'interagir avec les endpoints graphql.
ressource: https://github.com/swisskyrepo/GraphQLmap
Permet d'obtenir le schéma de l'API GraphQL même si l'introspection est désactivée.
ressource: https://github.com/nikitastupin/clairvoyance