HIGH graphql batching

Graphql Batching Attack

How Graphql Batching Works

GraphQL batching is a technique where multiple GraphQL queries are sent in a single HTTP request. Instead of making separate API calls for each operation, batching allows clients to combine multiple queries, mutations, or subscriptions into one payload. This optimization reduces network overhead and improves performance, especially for mobile applications or complex UIs that need to fetch related data simultaneously.

The batching mechanism typically uses an array of query objects, each containing a query string and optional variables. For example:

{
  "query": [
    {"query": "{ user(id: 1) { name } }"},
    {"query": "{ posts { title, author } }"},
    {"query": "{ comments { text, postId } }"}
  ]
}

When a GraphQL server processes a batched request, it executes each query independently and returns an array of responses in the same order. The server must handle each operation separately, maintaining proper isolation between them. This design creates an interesting attack surface: if the server doesn't properly validate or limit the scope of each operation, an attacker can craft malicious batches that exploit business logic flaws.

Graphql Batching Against APIs

Attackers have discovered that GraphQL batching can be weaponized against APIs in several ways. The most common attack involves exploiting the fact that multiple operations execute in a single context, potentially allowing privilege escalation or data exfiltration across different user sessions or data boundaries.

Consider a scenario where an API handles both user profile queries and administrative operations. A malicious batch might look like this:

{
  "query": [
    {"query": "{ user(id: 123) { email, balance } }"},
    {"query": "{ adminStats { totalUsers, revenue } }"}
  ]
}

If the server doesn't properly enforce authorization between operations, the attacker could access administrative data while authenticated as a regular user. The batching mechanism bypasses the typical request-level authorization checks because all operations share the same HTTP request context.

Another attack vector involves resource exhaustion. Attackers can craft extremely large batches containing hundreds or thousands of queries, overwhelming the server's processing capacity. Each query in the batch consumes CPU time and memory, and without proper limits, a single request can consume disproportionate resources.

Time-based attacks are also possible. An attacker might create a batch where each query performs a slow operation (like complex database joins or external API calls), causing the entire batch to take an excessive amount of time to complete. This can lead to denial of service conditions.

middleBrick's scanning engine detects these batching vulnerabilities by testing API endpoints with crafted payloads that attempt to bypass authorization boundaries and trigger resource exhaustion. The scanner evaluates whether the API properly isolates each operation within a batch and enforces consistent security policies across all operations.

Detection & Prevention

Detecting GraphQL batching vulnerabilities requires both automated scanning and manual code review. Automated tools like middleBrick can identify endpoints that accept batch requests and test them for common vulnerabilities. The scanner attempts to execute operations with different privilege levels in the same batch to check for authorization bypass.

Prevention strategies should be implemented at multiple layers:

  • Operation Limits: Implement strict limits on the number of operations per batch (e.g., maximum 10 queries per request). This prevents resource exhaustion attacks.
  • Depth Limiting: Set maximum query depth to prevent overly complex nested queries that could cause performance issues.
  • Timeout Controls: Implement per-operation timeouts rather than batch-wide timeouts to prevent slow operations from blocking the entire request.
  • Authorization Isolation: Ensure each operation in a batch is evaluated independently for authorization, using the same security context as if it were a standalone request.
  • Rate Limiting: Apply rate limiting at the batch level, not just per operation, to prevent abuse through high-volume batching.
  • Input Validation: Validate all variables and arguments for each operation, even when they're part of a batch.

For GraphQL servers, consider using libraries that provide built-in batching protections. Apollo Server, for example, includes configurable depth limiting and query complexity analysis. Always validate that your GraphQL implementation properly handles edge cases in batching scenarios.

middleBrick's continuous monitoring feature can help maintain security over time by regularly scanning your APIs for batching vulnerabilities, ensuring that security controls remain effective as your API evolves.

Frequently Asked Questions

Is GraphQL batching always a security risk?
No, batching itself is a legitimate performance optimization. The security risk comes from improper implementation. When properly secured with operation limits, authorization isolation, and resource controls, batching is safe. The vulnerability exists when servers don't enforce consistent security policies across all operations in a batch.
How can I test my API for GraphQL batching vulnerabilities?
You can test manually by crafting batch requests with mixed privilege levels and monitoring the responses. For comprehensive testing, use automated tools like middleBrick that specialize in API security scanning. These tools can systematically test for batching vulnerabilities, including authorization bypass attempts and resource exhaustion scenarios, without requiring you to write test scripts.