September 15, 2026
Complete Guide on GraphQL Testing — Part I
Hi everyone, in this article we’ll talk about GraphQL testing. I’m creating a complete series on this topic including some interesting…

By Rahul Singh Chauhan
4 min read
Hi everyone, in this article we'll talk about GraphQL testing. I'm creating a complete series on this topic including some interesting findings that I've been able to discover in the past. The series should be enough for one to start with GraphQL testing with nothing but BurpSuite in your arsenal.
GraphQL vs REST API
Often, a lot of companies use GraphQL instead of REST APIs for their services. But why? What's the need of GraphQL?
At a high level, both GraphQL and REST APIs allow clients to communicate with backend services. The major difference is how the client requests data.
In a traditional REST API, an application exposes multiple endpoints, with each endpoint generally representing a resource or operation.
For example, a typical REST API looks like the following:
GET /api/users/123
GET /api/users/123/orders
GET /api/products/456GET /api/users/123
GET /api/users/123/orders
GET /api/products/456The server determines what data is returned by each endpoint. If an application needs information from multiple resources, the client may have to make several requests.
GraphQL takes a different approach. Instead of exposing numerous resource-oriented endpoints, an application commonly exposes a single GraphQL endpoint, such as:
POST /graphqlPOST /graphqlThe client then specifies exactly what data it wants using a GraphQL query.
For example:
query {
user(id: 123) {
id
name
email
}
}query {
user(id: 123) {
id
name
email
}
}The server processes the query against its GraphQL schema and returns the requested fields ( id, name and email associated with the user with id 123):
{
"data": {
"user": {
"id": "123",
"name": "Alice",
"email": "alice@example.com"
}
}
}{
"data": {
"user": {
"id": "123",
"name": "Alice",
"email": "alice@example.com"
}
}
}This difference is particularly important during penetration testing.
With REST, a tester will typically start by enumerating endpoints, HTTP methods, parameters, headers, and request bodies. With GraphQL, the tester needs to understand the application's schema, operations, fields, arguments, and relationships between objects.
For example, a REST application might expose:
GET /api/users/123
GET /api/users/123/orders
GET /api/orders/456GET /api/users/123
GET /api/users/123/orders
GET /api/orders/456Whereas the equivalent GraphQL functionality could potentially be accessed through:
query {
user(id: 123) {
name
orders {
id
amount
}
}
}query {
user(id: 123) {
name
orders {
id
amount
}
}
}
This can create a different attack surface.
A GraphQL schema can expose a large number of objects and relationships through a relatively small number of HTTP endpoints. A tester therefore shouldn't assume that finding /graphql means the attack surface is small. The schema itself effectively becomes an important part of the application's attack surface.
Another important difference is that GraphQL allows the client to control the shape of the response. A client can request only the fields it needs:
query {
user(id: 123) {
name
}
}query {
user(id: 123) {
name
}
}or request additional nested information:
query {
user(id: 123) {
name
email
orders {
id
total
}
}
}query {
user(id: 123) {
name
email
orders {
id
total
}
}
}
From a security perspective, this makes questions such as authorization at the field level, excessive data exposure, nested queries, query complexity, and access to sensitive relationships particularly important during a GraphQL assessment.
One question that might be lingering in your mind is — if there's a way to figure out the complete set of fields expected (such as id, title, etc) by a particular query. We'll talk not one, but two ways which can be used to identify these fields.
Query vs Mutation Operations
REST APIs have methods such as GET, POST, PATCH, CONNECT, PUT, OPTIONS, etc. Similarly, GraphQL has Operations. GraphQL primarily uses two operation types that are important for a pentester: queries and mutations.
Queries
A query is used to retrieve data from the server.
The operation asks the server to retrieve a user and return three fields.
Queries are conceptually similar to GET operations in REST, although the underlying HTTP request is often a POST request when using GraphQL.
From a penetration-testing perspective, queries are particularly interesting because they can expose:
- User information
- Internal objects
- Administrative data
- Relationships between objects
- Sensitive fields
- Objects belonging to other users
- Data accessible through nested relationships
Mutations
A mutation is used when the client wants to modify server-side state (such as create, update, delete, upload files, etc.) For example:
Operation Names and Fields
To effectively test GraphQL, it is important to understand the terminology used to describe a GraphQL request.
Consider the following request:
There are several different components here.
Operation type
The first part is query. It could also have been mutation. or in more advanced cases subscription .
Operation name
The next part is: GetUser. This is the operation name.
The operation name is primarily used to identify an operation and can be particularly useful when an application sends multiple operations in the same GraphQL document.
Fields
The fields specify the actual data or functionality being requested. For example, in the above GraphQL request, the fields were id, name, email
Tools:
Though there are a bunch of tools like postman, we'll be relying on Burp Suite, because most of us are familiar with it and if you've got an updated version of BurpSuite, you get a GraphQL tab in the Proxy and the Repeater tabs.
GraphQL queries relies heavily on the correct placement of CRLF characters \r\n. With the GraphQL tab, you can just enter your input and hit the enter button. The placement of \r\n would be automatically taken care of by Burp.
That's it from an introduction perspective. In the upcoming articles, I'll be talking about basic and advanced concepts that one can use to exploit a service hosted over GraphQL.
Hope you enjoyed reading the article. Please consider subscribing and clapping for the article.
In case you are interested in CTF/THM/HTB writeups consider visiting my YouTube channel.