# GraphQL node resolver missing scope filter

Node/global-ID resolvers returning objects without the schema's scope or ownership filter

_Area: Web access control and IDOR. Seen in 2 disclosed reports; one confirmed bounty: $800; latest 2026-05-06. Updated 2026-11-01._

## How it works
GraphQL schemas often enforce access by filtering which entities a token may see (a scope or ownership filter applied per element resolver). The assumption that breaks: that every resolver applies that shared filter. A single resolver — a node lookup, a global-ID fetch, or a new feature query — that fetches the object directly, gated only by a coarse binary check, returns objects outside the caller's scope. The schema's scoping is only as strong as its weakest resolver.

## Where it shows up
- Element/node resolvers that omit the shared scope-filter helper its sibling resolvers call [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-gj2p-p9m4-c8gw.md)
- Resolvers gated only by a binary capability check (e.g. canQueryUsers) rather than per-object scope [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-gj2p-p9m4-c8gw.md)
- Event/activity/message fields on a node that embed protected data in human-readable strings [E2](https://bugbountylibrary.com/r/h1%3A1392032.md)
- Newly shipped feature queries that resolve across all tenants/programs [E3](https://bugbountylibrary.com/r/h1%3A1868473.md)
- Unauthenticated operations returning cross-tenant data [E3](https://bugbountylibrary.com/r/h1%3A1868473.md)

## How to review
Diff each element resolver against its siblings: every resolver returning a scoped entity must invoke the same scope/ownership filter. The invariant: for any resolver, the returned set is a subset of what the caller's token scope permits. Check that the only gate is not a coarse boolean. For node/global-ID lookups, confirm the fetched object is re-checked against the caller's scope, not just existence. For new feature queries, confirm authorization runs before data resolution and that unauthenticated access is denied.

## Variants seen
- Element resolver missing the shared scope helper, exposing PII/tax IDs across user groups [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-gj2p-p9m4-c8gw.md)
- Node event messages leaking order details to staff lacking read_orders, then a second service accepting the leaked identifier without re-checking permissions [E2](https://bugbountylibrary.com/r/h1%3A1392032.md)
- Unauthenticated cross-tenant query on a new feature path, also enabling oversized-request DoS [E3](https://bugbountylibrary.com/r/h1%3A1868473.md)

## Impact and severity
Cross-scope PII and tax-ID disclosure [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-gj2p-p9m4-c8gw.md), full order access beyond granted permissions [E2](https://bugbountylibrary.com/r/h1%3A1392032.md), and private program/scope leakage to unauthenticated users plus DoS [E3](https://bugbountylibrary.com/r/h1%3A1868473.md). Severity rises when the leaked identifier is reusable in another endpoint that skips its own permission check [E2](https://bugbountylibrary.com/r/h1%3A1392032.md), and when the query is unauthenticated and enumerable across tenants [E3](https://bugbountylibrary.com/r/h1%3A1868473.md).

## Evidence
- E1: https://bugbountylibrary.com/r/ghsa%3AGHSA-gj2p-p9m4-c8gw.md
- E2: https://bugbountylibrary.com/r/h1%3A1392032.md
- E3: https://bugbountylibrary.com/r/h1%3A1868473.md
