Skip to Security Test Cases section if you are an experienced pentester.
GraphQL is a API query language based on declarative data sampling, that is, the client can specify exactly what data he needs from the API. Instead of multiple API endpoints (REST), GraphQL represents a single endpoint that provides the client with the requested data.
Usually in the REST API, you need to get information from different endpoints. In GraphQL, in order to get the same data, you need to make one query indicating the data you want to receive. There are 3 main types of queries in GraphQL:
Here’s the sample HTTP request for a GraphQL endpoint.
POST /graphql HTTP/1.1
Host: example.com
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Authorization: Bearer <<<TRUNCATED>>>
Content-Type: application/json
Content-Length: 488
Origin: https://www.example.com
Connection: close
<<<TRUNCATED BODY>>>
Security Test Cases
Introspection is used to ask for a GraphQL schema for information about what queries, types and so on it supports. The information about Queries, Mutations, Types and so on would give an attacker many opportunities to find vulnerabilities and errors in processing in a specific GraphQL implementation.
This is enabled by default and must be disabled or restricted by developer. Here is a good link on how to disable Introspection in various programming languages: https://lab.wallarm.com/why-and-how-to-disable-introspection-query-for-graphql-apis/
The tool to test introspection query is InQL, available as Burp extension or command-line.
https://github.com/doyensec/inql
Here’s the Introspection query HTTP request looks like:
POST /graphql HTTP/1.1
Host: example.com
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/json
Content-Length: 746
Origin: https://example.com
Connection: close
Referer: https://example.com
{"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}}}}}}}}"}
The above HTTP request (when replaced with actual GraphQL endpoints) would give you queries, mutations, subscriptions, arguments if Introspection query is enabled.
There is a high chance that the GraphQL endpoint throws a verbose error to the end-user. The easiest and fastest way to trigger an error message is to insert malicious payload such as ‘, “, ; into the GraphQL query. Here’s the example.
POST /graphql HTTP/1.1
Host: example.com
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/json
Content-Length: 746
Origin: https://example.com
Connection: close
Referer: https://example.com
{"operationName":null,"variables":{"SearchStringValue":"example’"},"query":"query ($SearchStringValue: String!) <<<TRUNCATED>>>"}
GraphQL is just a layer between client apps and the database that makes it susceptible to Injection attack. We would recommend to perform this test manually or use Burp Intruder (with Logger++ extension) by inserting SQL Injection payloads in GraphQL query. Further exploitation can be performed by SQLmap tool.
Common GraphQL endpoints
Below are the common endpoints that you should try accessing during the penetration test.
In addition, run a specific web server scanner such as Nikto to identify any obvious issues.
This is an interesting vulnerability if the endpoint uses sequential ID or predictable user role name such as admin, reviewer, auditor, etc. You could try manipulating the values to assess the access control implementation within the application.
Here’s the useful tool list for the assessment.
You can reach us at hello@security-simplified.com for any questions or suggestions.
Happy Hacking!!!
Join our newsletter today and enhance your knowledge with valuable insights. It's quick, easy, and free!