vulns.co
/
GKData.io MCP

Back to Playbooks

GraphQL persisted queries

Automatic persisted queries and allow lists only help if an unknown operation is rejected. Authorization still has to run per field and per object after the hash is accepted.

Tags: graphql, authz, api

Level: advanced

Method

  1. See how the client calls GraphQL

    A hash plus a query, a hash alone, or a full query in the body are different modes. Record which one the app you are testing uses.

    Tools: Burp Suite

  2. Unknown hash

    Send a hash the server has not seen, on an account you own, without registering a new operation if the program forbids it. Rejection is the control. Acceptance of an arbitrary query is the note.

    Tools: Burp Suite

  3. Authz after the hash

    A persisted query that returns another user's object is still IDOR. The allow list did not replace object checks.

    Tools: Burp Suite

  4. Two roles

    Run one documented operation as two roles you own. Compare fields, not just HTTP status.

    Tools: Burp Suite

  5. Mutations

    Reads and writes are different operations. A locked query list that still accepts an unlisted mutation is the gap.

    Tools: Burp Suite

  6. Do not dump the graph

    Stay on objects you created. Introspection policy is the program's rule, not a default.

    Tools: browser

Field notes

  • The older GraphQL playbook covers introspection and batching. This page is the allow list.
  • APQ often registers the query on a cache miss. That is a feature until it bypasses an allow list the product claims to enforce.
  • Field-level authz failures belong in the report even when the operation hash was valid.

References