{
  "id": 12801870,
  "title": "GraphQL resolvers often check the top-level object and skip the nested ones",
  "url": "https://urgent.news/2026/10/08/graphql-resolvers-often-check-the-top-level-object-and-skip-the",
  "topic": "tech",
  "section": "Tech",
  "published": "2026-10-08T06:09:13.000Z",
  "source": {
    "name": "Dev.to",
    "slug": "dev-to",
    "url": "https://dev.to/authbyexample1/graphql-resolvers-often-check-the-top-level-object-and-skip-the-nested-ones-51ki"
  },
  "original_language": "en",
  "account": "Many GraphQL applications place the permission check in the root resolver, such as project(id: 7), which verifies if the user belongs to project 7 and returns the project object. After that, each nested field resolves independently. This means a query like project(id: 7) { linkedProjects { name members { email } } } can bypass the user's authorization for certain objects.\n\nFor instance, a linked project might belong to a different team, and its members resolver won't ask if the user can see that team. To address this issue, the authorization check should be placed in each type's resolver or in the data loader that fetches that type, using the object being returned as the key for authorization. Each field that returns another object should be treated as a new authorization question, even if the parent object was allowed.\n\nTo test this, sign in as a user who belongs to one project and query relations two or three levels deep. If any object from outside their project scope comes back, it is a security vulnerability. Introspection can provide a full list of these relations to test.",
  "summary": "A common GraphQL setup puts the permission check in the root resolver. project(id: 7) checks that you're a member of project 7 and returns it. Every nested field resolves on its own after that. So a query like project(id: 7) { linkedProjects { name members { email } } } can walk right out of the project you were allowed to see. A linked project might belong to another team, and its members…",
  "key_points": [
    "GraphQL resolvers often check top-level object, skip nested ones",
    "Authorization bypass possible in nested field resolvers",
    "Place authorization check in each type's resolver or data loader"
  ],
  "editors_take": "Shifting permission checks from the root resolver to each nested field's resolver or data loader ensures that users can only access authorized objects, even multiple levels deep in a query.",
  "illustration": null,
  "coverage": {
    "outlets": 1,
    "also_reported_by": []
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}