GraphQL without query depth and complexity limits is a denial-of-service vector with a trivially crafted payload: a malicious query that nests deeply-related types exponentially expands server-side resolution work while staying small on the wire (CWE-770, CWE-400). OWASP API 2023 flags this as unrestricted resource consumption (API4). A single deeply-nested query can saturate database connections and CPU for seconds, affecting all concurrent users. Without introspection controls, attackers also gain a complete map of your schema for free.
High because a single malicious query with exponential field nesting can exhaust server resources and produce a denial-of-service condition against all users of the API.
Add depth and complexity limits to your GraphQL server configuration before accepting public traffic. For Apollo Server:
import depthLimit from 'graphql-depth-limit'
import { createComplexityLimitRule } from 'graphql-validation-complexity'
const server = new ApolloServer({
typeDefs,
resolvers,
validationRules: [
depthLimit(6),
createComplexityLimitRule(1000),
],
})
For GraphQL Yoga, use the built-in useDepthLimit() and useQueryComplexity() plugins. Set max depth to 5-7 (enough for most legitimate queries) and tune complexity to allow your most expensive real query with 20-30% headroom. Disable introspection in production if your API is not public: introspection: process.env.NODE_ENV !== 'production'.
saas-api-design.api-security.graphql-depth-limitshighgraphql-depth-limit package usage, graphql-query-complexity package, Apollo Server validationRules with depth/complexity plugins, Yoga/Pothos built-in complexity config, or manual depth checking. Without these limits, a malicious query can nest deeply enough to exhaust server resources.graphql, @apollo/server, graphql-yoga, pothos-graphql, nexus, or type-graphql in package.json; no .graphql schema files; no GraphQL endpoint in routes.Apollo Server configured with no validation rules. Note what's missing (e.g., "Apollo Server configured with no validation rules; graphql-depth-limit and graphql-query-complexity not in dependencies"). Max 500 chars.src/ or app/api/graphql/. For Apollo Server, use the graphql-depth-limit package: validationRules: [depthLimit(5)]. For complexity limiting, use graphql-query-complexity with a max complexity threshold appropriate to your schema. For GraphQL Yoga, use the built-in useDepthLimit() and useQueryComplexity() plugins. A reasonable starting point is max depth of 5-7 and a complexity limit that allows your most complex legitimate query with 20-30% headroom. Also consider disabling introspection in production if your API is not public.