Vulnerabilities in GraphQL - Overview and Case Studies
This disclosure capability of GraphQL is both strength and weakness at the same time and should be tested accordingly.

What Is GraphQL?
GraphQL is a query language for APIs. As the name suggests, it is particularly well suited for querying data that can be represented as a graph. Compared to the widely used REST APIs, GraphQL offers several advantages, which are described in the following section. To provide a fair comparison, the core functionality of both technologies is briefly outlined.
A REST API consists of a set of endpoints, with the number varying depending on the data available to the client. Each endpoint is mapped to an entity and returns information about that entity. If a client needs to query information about multiple entities, it must make a separate request to each respective endpoint. This approach is highly inefficient compared to GraphQL and creates significant management overhead.
In GraphQL, there is only a single endpoint through which the client communicates. The client submits a query and receives a response. This broad query capability is both a strength and a weakness of GraphQL. A REST API limits the information retrievable in a single request by constraining the scope of each endpoint. GraphQL, on the other hand, supports arbitrary queries across the data, meaning a single query can return a large volume of data.
The GraphQL Schema
GraphQL uses a schema to describe its data. The schema defines exactly which queries and mutations are available to clients.
In addition, there is the introspection schema, which allows you to query a GraphQL application for information about its supported operations. The introspection schema can be retrieved with the following query. You can also use various GraphQL IDEs or tools like GraphQL Voyager to query the introspection schema.
Vulnerabilities and How to Prevent Them
According to the OWASP Foundation, the most common attacks against GraphQL are:
- Injection -- including SQL and NoSQL injection, OS command injection, SSRF (Server Side Request Forgery), and CRLF (Carriage Return Line Feed) injection/request smuggling
- DoS (Denial of Service)
- Exploiting weak authorization
- Batching attacks -- a GraphQL-specific method of brute-force attack
- Abuse of insecure default configurations
Injection
GraphQL itself does not provide any built-in protection against injection attacks. If no safeguards have been implemented -- such as parameterized queries -- the application may be vulnerable to any type of injection. Therefore, all incoming data should be validated to ensure that only legitimate values are accepted. Invalid input should always be rejected without revealing excessive details about the API's internal workings. Use parameterized queries in the backend to process user-supplied data securely. Additionally, ensure that the client sanitizes all data from the GraphQL response before rendering it. Implementing an appropriate Content Security Policy is also strongly recommended.
Denial of Service
DoS is an attack on the availability and stability of the API that can cause it to become slow, unresponsive, or entirely unavailable. It is therefore advisable to implement pagination to limit the amount of data returned in a single response. Additionally, deploying a rate limiter per user or per IP address is highly recommended.
Exploiting Weak Authorization
Exploiting weak authorization logic is by far the most common vulnerability in GraphQL-based applications. It is essential to implement robust authentication and authorization mechanisms. Every client request should be verified to confirm that the client is authorized to access the requested data.
Batching Attacks
GraphQL supports combining multiple queries into a single request -- a feature known as query batching. This allows the client to bundle queries for multiple object instances into one call, which in turn enables batching attacks, a specialized form of brute-force attack. To prevent this type of attack, batching should be disabled for sensitive objects such as usernames, email addresses, passwords, OTPs, and session tokens. This forces an attacker to make a separate network call for each object instance, similar to attacking a REST API. Additionally, the number of concurrent requests should be limited.
Abuse of Insecure Default Configurations
A common example is the use of "hidden" API endpoints. These are often created for functionality that should not be publicly accessible. Such endpoints are generally a poor practice -- but when they are accessible without proper authorization, the risk is significantly greater, especially in the GraphQL environment.
To improve developer experience, GraphQL provides introspection, which is enabled by default in most implementations. Introspection allows API clients to dynamically query information about the schema, including documentation and types for every query and mutation defined within it. Development tools such as the GraphiQL IDE also rely on this feature to retrieve the schema dynamically. When introspection is enabled, an attacker can obtain the full GraphQL schema to map out the entire attack surface of the API.
When encountering a GraphQL API, the first step is typically to run an introspection query and obtain a copy of the schema. This schema provides a comprehensive view of the exposed API's attack surface.
The safest and simplest approach is to disable introspection and GraphiQL system-wide. You should also disable the built-in field suggestion feature, which returns hints when a requested field name closely resembles an existing field. Likewise, disable detailed error messages such as stack traces to prevent attackers from gaining valuable information about the system.
Conclusion
In this post, we examined the core functionality and security requirements of GraphQL. Authentication and authorization are the first challenges that need to be addressed. Beyond that, we demonstrated how common GraphQL-related attack surfaces can be effectively reduced.
Sources to Practice On
To practice the attack techniques described above and see them in action, the following resources are available.
Damn Vulnerable GraphQL Application
TryHackMe - GraphQL Room