Persisted query allowlist bypass
Persisted queries are an allowlist only if the server refuses documents it did not already trust. Automatic registration, a store keyed only by hash, or a check that runs on one HTTP method and not the other, lets a caller run an operation the UI never…
Tags: graphql, persisted-query, authz, api
Typical severity: P3-P4
What it becomes
Low alone when unknown hashes are rejected, and it becomes a hidden operation when the server accepts a query document that was not in the trusted set.
Where to look
GraphQL gateways with an operation allowlistautomatic persisted-query registrationGET and POST on the same GraphQL path
Chains
- Allowlist bypass: The server executes a full query document when the hash is unknown, or registers that document for later, instead of rejecting it.
- Cross-caller execution: A persisted query saved by a more privileged user or another tenant is executed by a different caller because the store is global and the operation authorization is not re-checked.
Notes
- Introspection being off is not this bug. This bug is a trusted-query list that is not actually closed.
- Run only operations against objects you own. A saved query that returns another tenant's fields is the authorization finding, not a reason to dump the store.