← All casesConfidential · Anonymized
Case
#022
Developer Platform · Severity: Medium-High
GraphQL Depth & Cost Exhaustion
Unbounded GraphQL resolver fan-out enabled cheap client queries to consume disproportionate backend resources. Under adversarial or accidental patterns, the database connection pool saturated and downstream services experienced collateral degradation.
Industry
Developer Platform
Scope
API · GraphQL · Database
Timeline
R·Q1 → V·Q1 → R·Q2
Closed
Q2
01
Impact
DB pool saturation
95th-percentile pool wait: 30 ms → 1200 ms under crafted queries
Collateral impact
2 unrelated services shared the pool and experienced 502s
Cost of attack
Single client query, no auth escalation required
Impact vectors
- ›Database pool saturation
- ›Collateral service degradation
02
Reproduction
Steps below reproduce the finding against a staging replica. Where the reproduction affected a shared component, coordination was arranged before execution.
- 01Enumerate the schema via a low-privilege session (introspection partially restricted, sufficient signal remained).
- 02Compose a single query with nested pagination across 4 related types.
- 03Observe sustained backend DB pool saturation from a single connection.
03
Vulnerability
type Organization {
id: ID!
members(first: Int = 100): [Member!]!
}
type Member {
id: ID!
projects(first: Int = 100): [Project!]!
}
type Project {
id: ID!
events(first: Int = 100): [Event!]!
}
# no depth limit, no cost analysis, no per-request budget04
Mitigation
Client-side mitigation shipped and validated during the engagement. Reference patch below.
import { costAnalysis } from '@escape.tech/graphql-armor-cost-limit';
import depthLimit from 'graphql-depth-limit';
const server = new ApolloServer({
schema,
validationRules: [
depthLimit(6),
costAnalysis({
maxCost: 1500,
objectCost: 1,
scalarCost: 0,
depthCostFactor: 1.6,
}),
],
});05
Retest & Verify
- ✓Crafted queries now rejected with a cost-limit error before execution.
- ✓DB pool wait returned to baseline under identical workload.
- ✓Analytics read replica introduced for large-scan queries; no cross-service impact observed.
06
Deliverables
- ▊Technical Report
- ▊Query cost model
- ▊Depth-limit and cost-analysis patch
- ▊Retesting report
07
Sign-off
Handled by
Epulyx
Reviewed by
Ben Payer
Closed
Case closed after cost-model rollout validation.