GraphQL's Single Endpoint Demands Smarter Defenses

Cloudflare's API Gateway now includes protection for GraphQL APIs against two of the most common abuse vectors: deeply nested queries and queries that request more data than necessary. These attacks can effectively cause a denial of service at the origin, yet they look like legitimate traffic to conventional security tooling.

GraphQL APIs typically expose a single endpoint, unlike REST APIs with their dozens or hundreds of discrete routes. That endpoint accepts highly flexible queries, which is what makes GraphQL so useful—but also what makes it dangerous. An abusive request can exploit recursive data relationships or trigger N+1 query problems, placing disproportionate load on the origin. Because the entire attack fits into a single HTTP request, rate limiting alone cannot stop it.

To address this, Cloudflare needed visibility inside the GraphQL request itself. That meant building a query parser that could run at the edge without adding meaningful latency.

The Problem With Standard Parsers

Before adding security features, Cloudflare's team wanted to gather data on query depth and size. Their target was a p95 parsing time under 50 microseconds. They evaluated existing open-source GraphQL parsers but found their performance to be insufficient—risking hundreds of microseconds of added latency per request.

There was also an infrastructure constraint: the system used had a strict no-heap-allocation policy. Any memory a parser needed had to be reused across subsequent requests. Building a full abstract syntax tree, which requires unpredictable heap allocations, was off the table.

The solution was to skip tree construction entirely. Instead, Cloudflare built a custom GraphQL lexer that converts raw input into a list of lexical tokens—comments, strings, variable names, parentheses, and so on. From that token stream, the parser can infer query depth and size using heuristics, without fully validating the query or building a structured representation.

Handling JSON-Encoded Queries

Most GraphQL queries arrive as HTTP POST requests with either application/json or application/graphql content types. The application/graphql format is straightforward: the raw query is ready to parse. JSON-encoded queries present a challenge because escape sequences need to be removed, and typical deserialization libraries allocate new memory for the unescaped string.

Cloudflare worked around this by using serde's RawValue to locate the JSON field containing the query, then iterating over the bytes one at a time, feeding them into the tokenizer while stripping escape sequences on the fly. This avoids any heap allocation while still handling JSON payloads correctly.

In an initial trial against tens of thousands of requests per second, the parser achieved a p95 time of 25 microseconds. There are some GraphQL syntactic features that the parser cannot handle and must fail open on, but for the common cases the approach is both fast and sufficient for security analysis.

New Security Fields for API Gateway

API Gateway customers can now retrieve information about the depth and size of GraphQL queries seen at the edge via Cloudflare's GraphQL API. In an analysis of over 400,000 data points from a production domain, queries almost never requested more than 60 fields and never went beyond seven levels deep.

Those insights translate directly into security rules. Cloudflare added three new Wirefilter fields for GraphQL protection:

  • cf.api_gateway.graphql.parsed_successfully
  • cf.api_gateway.graphql.query_depth
  • cf.api_gateway.graphql.query_size

Cloudflare recommends including cf.api_gateway.graphql.parsed_successfully in all rules, as this ensures forward compatibility with future GraphQL protection releases. Customers who identify outliers in their traffic can create custom rules to log unusual queries for further review.

What's on the Roadmap

Cloudflare is already planning the next iteration of GraphQL protection. Upcoming features include integration with complexity-based rate limiting, where query cost is calculated automatically and rate limits are applied based on total query execution cost over a session. Customers will also be able to configure which specific endpoints the GraphQL security features apply to.

The team is also building data insights that correlate query complexity with origin response times, as well as automatic threshold recommendations based on historical traffic trends.