Skip to content

fix: GraphQL depth-limit probe uses real schema fields instead of guessed names#76

Merged
GovindarajanL merged 1 commit into
OWASP:mainfrom
GovindarajanL:fix/71-graphql-depth-limit-probe
Jul 25, 2026
Merged

fix: GraphQL depth-limit probe uses real schema fields instead of guessed names#76
GovindarajanL merged 1 commit into
OWASP:mainfrom
GovindarajanL:fix/71-graphql-depth-limit-probe

Conversation

@GovindarajanL

Copy link
Copy Markdown
Collaborator

Fixes #71

Summary

The query-depth-limit check sent a hardcoded deeply-nested query built from placeholder field names (a, b, c, ...). Every real GraphQL schema rejects that at schema validation (HTTP 400 "Cannot query field") before depth is ever assessed, so the check could never produce a true positive against any real target.

Reproduction

Scanned DVGA. Introspection and batch-query-abuse were correctly detected, but no depth-limit finding was ever produced. Replaying the exact probe by hand:

$ curl -s -X POST http://127.0.0.1:5000/graphql -d '{"query":"{a{b{c{d{e{f{g{h{i{j}}}}}}}}}}"}'
{"errors":[{"message":"Cannot query field \"a\" on type \"Query\"."}]}

Fix

Rebuilds the probe from __Type.ofType, a self-referencing field mandated by the GraphQL introspection spec on every compliant server, so it reaches real depth resolution instead of failing validation.

Also fixes a latent sibling bug in the introspection check: it accepted any 2xx response containing the substring "__schema", but a disabled-introspection error message (Cannot query field "__schema"...) matches that same substring, which would have caused a false "introspection enabled" finding. Now requires a real "data" body with no "errors".

Verification

  • Re-ran against DVGA after the fix: "GraphQL Query Depth Limit Not Enforced" (MEDIUM) now fires correctly. Manually replayed the new probe and confirmed a genuine "data" response with no "errors".
  • New regression tests: probe payload asserted to use ofType chaining (not guessed names) via an ArgumentCaptor, and the introspection check asserted to not false-positive on an error message that mentions __schema.
  • Full suite passes (241 tests).

Test plan

  • mvn test passes
  • Re-scanned DVGA with the fixed jar — depth-limit finding now fires, manually verified as accurate

…ssed names

The query-depth-limit check sent a hardcoded deeply-nested query built
from placeholder field names ("a", "b", "c", ...). Every real GraphQL
schema rejects that at schema validation (HTTP 400 "Cannot query field")
before depth is ever assessed, so the check could never produce a true
positive against any real target.

Reproduced against DVGA: no depth-limit finding was ever produced, and
replaying the exact probe payload by hand confirmed the 400.

Rebuilds the probe from __Type.ofType, a self-referencing field mandated
by the GraphQL introspection spec on every compliant server, so it
reaches real depth resolution instead of failing validation. Also fixes
a latent sibling bug in the introspection check, which accepted any 2xx
response containing the substring "__schema" -- a disabled-introspection
error message ("Cannot query field \"__schema\"...") matches that same
substring. Now requires a real "data" body with no "errors".

Fixes OWASP#71

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@GovindarajanL
GovindarajanL merged commit 35c0932 into OWASP:main Jul 25, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

GraphQL query-depth-limit check can never fire — probe query fails schema validation

1 participant