Lion Cipher Lab
Attack and defend a GraphQL API (introspection, resolver authz, and query-shape DoS)
- AppSec / DevSecOps
- Intermediate
- ~75 min
- Free · no account required
Why it matters
GraphQL is now the shape of a huge share of modern APIs, and it fails in ways REST testing habits completely miss. A REST API is many URLs, one verb each, with a WAF and a rate limiter you can hang off each endpoint. A GraphQL API is the opposite: one endpoint (usually /graphql), one POST, and the client asks for exactly the fields it wants in a single query. That one design choice quietly disables a pile of controls teams assume they still have — per-endpoint rate limits (there is only one endpoint), per-URL WAF rules (every request is the same URL and verb), and 'scan every endpoint'…
What you'll learn
- reading a GraphQL API as one endpoint / one POST where the client picks the fields — and why that breaks per-endpoint WAF rules, per-URL rate limits, and 'scan every endpoint' tooling
- running an introspection query with curl and reading back every type, field, and mutation the server exposes
- explaining why disabling introspection is defence in depth, not a fix — field suggestions ('did you mean') and error messages still leak the schema
- finding a field that returns data the caller should not see, and stating the fix: authorization belongs on each field's RESOLVER, because there is only one endpoint
- reproducing denial of service by query SHAPE — deeply nested/cyclic queries and alias amplification (many aliased copies of an expensive field in one request) — and batched arrays of operations
- seeing why a batch of aliased login attempts brute-forces a password under a per-request rate limit, and why rate limiting must be cost-aware, not request-count-aware
- writing a concrete GraphQL hardening checklist — depth limiting, cost/complexity budgets, alias/batch caps, timeouts, and persisted queries / trusted documents — mapped to the exact attacks you ran
- doing all of it strictly against a deliberately vulnerable app you run yourself on localhost, never against anyone else's API
Steps in this lab
- The one rule: your machine, your target, nobody else's
- The GraphQL shape in one breath — and why REST habits stop working
- Stand up your own vulnerable GraphQL target in Docker
- Introspection: ask the API for its own blueprint
- Field-level authorization: reach data the resolver never protected
- Denial of service by query SHAPE: nesting, cycles, and alias amplification
- Batching as a brute-force engine: many login attempts, one request
- Now defend it: the hardening checklist, mapped to what you just did