Breach report
GraphQL batching and introspection: when flexibility becomes attack surface
What happened
This is a vulnerability class rooted in how GraphQL APIs are commonly configured, not a single company's breach. PortSwigger's Web Security Academy documents two recurring failure patterns. First, introspection — a built-in feature that lets a client query the server for its entire schema — when left enabled in production, exposes the full API structure, including sensitive or hidden fields. Second, aliasing and batching: because aliases let a client pack many operations into one HTTP request, rate limiters that count *requests* rather than *operations* can be defeated, letting an attacker "brute-force authentication codes or discount codes at scale." GraphQL endpoints that accept GET or form-encoded POST requests are additionally exposed to CSRF.
The through-line is that convenience features designed for developers double as reconnaissance and throughput tools for attackers.
Root cause
Two weaknesses combine. Improper control of interaction frequency (CWE-799) lets aliased/batched operations bypass request-counting rate limits, enabling improper restriction of excessive authentication attempts (CWE-307) — brute force. Unrestricted introspection is an information-exposure problem that hands attackers the schema map. Both fall under OWASP's Broken Access Control and related API-security concerns: the server enforces limits and disclosure controls at the wrong granularity.
How it would have been caught
An API security test that sends a single batched request with many aliased login attempts and asserts the rate limiter still blocks it would fail against a naive per-request limiter. An introspection query (__schema) fired at production and expected to be refused reveals whether the schema is exposed. A reproduction packs N authentication guesses into one request and confirms all N are processed.
How to prevent it
- Disable introspection on production/private APIs.
- Rate-limit by operation and cost, not by HTTP request; add query-depth, complexity, and batch-size limits.
- Enforce per-account attempt limits on sensitive operations so batching cannot amplify brute force; require JSON POST and CSRF protection.
The Breachwire test (red → green)
Send one request containing many aliased authentication attempts and confirm the rate limiter processes all of them; fire an introspection query and confirm the schema is returned — the RED controls. Add operation-level rate limiting with depth/batch caps and disable introspection, then confirm the batched attempts are throttled and introspection is refused while legitimate queries still work.