Skip to content

Should Keystone enforce GraphQL query depth limits by default? #9789

@n0wsh

Description

@n0wsh

Context

Multiple independent security researchers (myself and @nedlir) have independently identified that Keystone's GraphQL API has no query depth limiting, complexity analysis, or cost budgeting.

A single unauthenticated request with a deeply-nested circular relationship query (e.g. users → posts → author → posts → author → ...) triggers exponential database queries. In local testing against a SQLite database with 6 total records, a depth-16 query caused a 38-second server hang.

This is classified as CWE-400: Uncontrolled Resource Consumption.

What other GraphQL frameworks do

Framework Default depth limit Complexity analysis
Hasura Yes (built-in) Yes
PostGraphile Configurable Yes (cost analysis)
graphql-ruby max_depth + max_complexity Yes
Lighthouse (Laravel) Yes (configurable) Yes
Keystone None None

Reproduction

Any Keystone project with bidirectional relationships (the standard pattern):

# No authentication required (with allowAll access)
{
  users {
    posts {
      author {
        posts {
          author {
            posts {
              author {
                posts {
                  author { id }
                }
              }
            }
          }
        }
      }
    }
  }
}

Measured response times (SQLite, 1 user + 5 posts + 15 comments):

Depth Time
12 0.9s
14 4.2s
16 38s (timeout)

Proposal

Add a default query depth limit (e.g. 10) using graphql-depth-limit or equivalent, with a configuration option:

export default config({
  graphql: {
    maxDepth: 10, // default, configurable
  },
})

Questions

  1. Should Keystone ship with a default query depth limit?
  2. Should this be treated as a security advisory or a hardening improvement?
  3. What default depth limit would be appropriate?

cc @nedlir @dcousens

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels
    No fields configured for Feature.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions