# GraphQL

O GraphQL não é um banco de dados (apesar do nome lembrar bastante algo como SQL), mas ele nos oferece uma boa maneira de obter metadados sobre as informações disponíveis (semelhante à tabela `information_schema` do MySQL). Podemos por exemplo, saber o que está disponível. Isso pode causar um risco à segurança, pois invasores podem conseguir acesso a informações que não poderiam ser expostas (segurança por obscuridade).

### Localizando o GraphQL

Geralmente o GraphQL está em algum subdomínio, como `graphql.site.com`, ou em subdiretórios como `site.com/graphql`, `site.com/graphql.php`, `site.com/graphiql` (versão GUI) e `site.com/graphql/console`.

### Instrospection

#### Ativo

É sempre útil solicitar informações a um esquema GraphQL para saber quais consultas ele suporta e podemos fazer isso através do Introspection. Para a alegria do atacante, o Instrospection já vem habilitado por padrão no GraphQL. Segue abaixo algumas queries possíveis de fazer quando o Instrospect está ativo:

Consultando os tipos de dados disponíveis

```bash
{
  __schema {
    types {
      name
    }
  }
}
```

Descobrindo um bom lugar para começar a explorar quais consultas estão disponíveis. Quando projetamos nosso sistema de tipos, especificamos em que tipo todas as consultas começariam.

```bash
{
  __schema {
    queryType {
      name
    }
  }
}
```

Com a consulta abaixo, podemos extrair todos os tipos, seus campos e seus argumentos (e o tipo dos args). Isso será muito útil para saber como consultar o banco de dados.

```bash
{__schema{types{name,fields{name, args{name,description,type{name, kind, ofType{name, kind}}}}}}}
```

Uma boa forma também de trazermos todos os dados necessários, é utilizando o payload com URL Encode, da seguinte forma.

```
fragment+FullType+on+__Type+{++kind++name++description++fields(includeDeprecated%3a+true)+{++++name++++description++++args+{++++++...InputValue++++}++++type+{++++++...TypeRef++++}++++isDeprecated++++deprecationReason++}++inputFields+{++++...InputValue++}++interfaces+{++++...TypeRef++}++enumValues(includeDeprecated%3a+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++++++++++++++}++++++++++++}++++++++++}++++++++}++++++}++++}++}}query+IntrospectionQuery+{++__schema+{++++queryType+{++++++name++++}++++mutationType+{++++++name++++}++++types+{++++++...FullType++++}++++directives+{++++++name++++++description++++++locations++++++args+{++++++++...InputValue++++++}++++}++}}
```

#### Inativo

É​ cada vez menos comum acharmos GraphQL com Instrospection ativo, mas isso não nos empede de mapearmos as suas informações. Para isso, podemos contar com o `Clairvoyance` para nos ajudar nessa missão.

### Mutations

As Mutation podem ser utilizadas para inserir dados. Note que abaixo estamos inserindo algumas informações entre parentes e depois estamos passando alguns campos entre chaves, que servem pra informar ao GraphQL o que ele devolver de informação após a inserção. Então inserimos nome e ano, porém só irá ser retornado o nome ao realizar a inserção.

```json
mutation {
  addPerson(name: "Mysther", year: 12) {
    person {
      name
    }
  }
}
```

### Fragments

Os Fragments, são utilizado para evitar que uma query tenha uma escrita repetitiva, servindo assim como uma espécia de função/método. Abaixo um exemplo de utilização de Fragment, para tratar duas chamadas de pesquisas de usuário.

```
{
  mysther1: searchPerson(name: "Mysther1") {
    ...myCustomFragment
  }
  mysther2: searchPerson(name: "Mysther2") {
    ...myCustomFragment
  }
}

fragment myCustomFragment on Person {
  languages {
    edges {
      node {
        name
      }
    }
  }
}
```

### Mensagens de Erro

Mensagens de erro também podem nos dar boas dicas de uso, entre informações que também podem ser importantes. Abaixo segue algumas queries que podem provocar boas mensagens de erro.

```bash
{}
{__schema}
{algoquenaoexiste}
```

### GraphQL Voyager

Ferrementa offline e online (link no final da página) que recebe o resultado de uma query contra um GraphQL com Instrospection ativo e a partir desse resultado, realiza uma demonstação gráfica sobre a estrutura do alvo.

O primeiro passo para isso, é confirmar que o cliente possui o Instrospection ativo e, então, utilizar a seguinte query:

```
{__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 }}}}}}}}
```

Copie o resultado da query, vá no GraphQL Voyager, clique em `Change Schema`, vá na aba `Instrospection`, cole o resultado e clique em `Display`.

### Graphqlmap

```bash
python3 graphqlmap.py -u <https://site.com/graphql>
dump_new
```

#### Sites

```bash
# GraphQL Voyager
https://apis.guru/graphql-voyager/

# Clairvoyance
https://github.com/nikitastupin/clairvoyance

# Graphqlmap
https://github.com/swisskyrepo/GraphQLmap
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://mysther.gitbook.io/knowledge-base/ataques/web-exploitation/injections/sql-injection/graphql.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
