CVE-2025-32034
Executive Summary
CVE-2025-32034 is a high-severity Denial of Service (DoS) vulnerability in the Apollo Router Core, a high-performance GraphQL router written in Rust for federated supergraphs using Apollo Federation 2. The vulnerability allows an attacker to craft queries with deeply nested and reused named fragments, causing exponential resource consumption during the query planning phase. This can lead to excessive CPU and memory usage, potentially crashing the router and denying service to legitimate users. The issue has been patched in versions 1.61.2 and 2.1.1. No public exploit code or proof-of-concept is currently available, and the EPSS score is 0.0%, indicating low exploitation likelihood at this time.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
This vulnerability affects the Apollo Router Core, which is distributed as a Rust binary and container image. Organizations using Apollo Router in their GraphQL infrastructure should verify their deployment version and update to the patched releases immediately. The package is not distributed via npm, PyPI, Go, or Ruby, but rather as a standalone binary or Docker image from Apollo's official repositories.
CVSS Breakdown & Threat Level
- CVSS Score: 7.5 (High)
- Attack Vector: Network (AV:N)
- Attack Complexity: Low (AC:L)
- Privileges Required: None (PR:N)
- User Interaction: None (UI:N)
- Scope: Unchanged (S:U)
- Confidentiality Impact: None (C:N)
- Integrity Impact: None (I:N)
- Availability Impact: High (A:H)
The vulnerability is remotely exploitable without authentication, making it a significant threat to availability. The low attack complexity and lack of required privileges increase the risk, though the absence of public exploits and low EPSS score currently reduce the immediate threat level.
Deep Dive & Mechanics
The Apollo Router processes GraphQL queries by first parsing them into an Abstract Syntax Tree (AST), then performing query planning to determine how to fetch data from the underlying subgraphs. Named fragments in GraphQL allow reuse of field selections, but when deeply nested and reused, they can cause exponential expansion during the planning phase.
Root Cause: The vulnerability lies in the named fragment expansion logic. For each fragment spread in a query, the router would expand the referenced fragment inline. When fragments reference other fragments in a deeply nested structure, and those fragments are reused multiple times, the expansion becomes exponential. For example, a query with 10 levels of nesting and 2 fragment spreads per level could result in 2^10 = 1024 expansions, but with reuse, this can grow much larger.
Attack Vector: An attacker sends a malicious GraphQL query with deeply nested named fragments that reference each other in a way that causes exponential expansion during query planning. The router's CPU and memory are consumed, leading to a denial of service.
Impact: The router becomes unresponsive or crashes, preventing legitimate GraphQL queries from being processed. This can disrupt services relying on the federated supergraph.
Vulnerable vs. Patched Code
The vulnerable code is in the query planning module, specifically in the fragment expansion logic. The patched version introduces caching or memoization to avoid re-expanding the same fragment multiple times.
Vulnerable Code (Conceptual):
fn expand_fragment(fragment: &Fragment, context: &Context) -> Vec<Field> {
let mut fields = Vec::new();
for spread in &fragment.spreads {
let referenced = context.get_fragment(spread.name);
// Recursive expansion without memoization
fields.extend(expand_fragment(referenced, context));
}
fields
}
Patched Code (Conceptual):
fn expand_fragment(fragment: &Fragment, context: &Context, cache: &mut HashMap<String, Vec<Field>>) -> Vec<Field> {
if let Some(cached) = cache.get(&fragment.name) {
return cached.clone();
}
let mut fields = Vec::new();
for spread in &fragment.spreads {
let referenced = context.get_fragment(spread.name);
fields.extend(expand_fragment(referenced, context, cache));
}
cache.insert(fragment.name.clone(), fields.clone());
fields
}
The patched version uses a cache to store expanded fragments, preventing redundant and exponential expansion.
Exploitation & Lab Setup
Red Team
Objective: Craft a malicious GraphQL query to cause denial of service.
Lab Setup:
- Deploy a vulnerable Apollo Router (version < 1.61.2 or < 2.1.1) with a federated supergraph.
- Use a tool like
curlor a GraphQL client to send the malicious query.
Malicious Query Example:
query Malicious {
a {
...F1
}
}
fragment F1 on Query {
b {
...F2
}
}
fragment F2 on Query {
c {
...F1
}
}
This query creates a cycle between fragments F1 and F2, causing infinite recursion. In practice, the router may have depth limits, but deeply nested non-cyclic fragments can still cause exponential expansion.
Exploitation Steps:
- Identify a vulnerable Apollo Router endpoint.
- Send the crafted query with deeply nested fragments.
- Monitor the router's resource usage (CPU/memory) to confirm DoS.
Blue Team
Detection:
- Monitor for GraphQL queries with excessive nesting depth or fragment reuse.
- Use rate limiting and query complexity analysis to block malicious queries.
Mitigation:
- Update to patched versions (1.61.2 or 2.1.1).
- Implement Web Application Firewall (WAF) rules to detect and block deeply nested fragments.
- Set query depth limits in the Apollo Router configuration.
Configuration Example:
# Apollo Router configuration
limits:
max_depth: 10
max_fragment_spreads: 50
Indicators of Compromise (IOCs)
- Network: GraphQL queries with deeply nested named fragments (depth > 10) and high fragment reuse.
- Logs: Router logs showing excessive query planning time or memory allocation errors.
- System: High CPU and memory usage on the Apollo Router process.
- Error Messages: "Query planning timeout" or "Out of memory" errors in router logs.
Detection Engineering
YARA Rule
rule CVE_2025_32034_GraphQL_Fragment_DoS {
meta:
description = "Detects malicious GraphQL queries with deeply nested fragments"
author = "Valters IT"
date = "2025-04-17"
cve = "CVE-2025-32034"
strings:
$fragment = "fragment " nocase
$spread = "...F" nocase
$deep_nest = /(\.\.\.\w+\s*\{){5,}/ // 5+ levels of nesting
condition:
$fragment and $spread and $deep_nest
}
Sigma Rule
title: CVE-2025-32034 - Apollo Router Fragment Expansion DoS
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects GraphQL queries with deeply nested fragments targeting Apollo Router
author: Valters IT
date: 2025-04-17
logsource:
category: webserver
product: apollo_router
detection:
selection:
http.method: POST
http.body|contains:
- "fragment "
- "..."
condition: selection
falsepositives:
- Legitimate complex GraphQL queries
level: high
Suricata Rule
alert http any any -> any any (msg:"CVE-2025-32034 Apollo Router Fragment Expansion DoS"; flow:to_server; content:"POST"; http_method; content:"fragment "; http_client_body; content:"..."; http_client_body; depth:1000; pcre:"/(\.\.\.\w+\s*\{){5,}/Ri"; classtype:attempted-dos; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Update Apollo Router to version 1.61.2 or 2.1.1 (or later).
- If immediate patching is not possible, implement query depth limits and fragment spread limits in the router configuration.
- Deploy a WAF to filter malicious GraphQL queries.
Long-term Measures:
- Regularly update Apollo Router to the latest version.
- Monitor for new CVEs and apply patches promptly.
- Implement query complexity analysis to detect and block expensive queries.
Workaround Configuration:
# apollo-router.yaml
limits:
max_depth: 10
max_fragment_spreads: 50
max_query_planning_time_ms: 5000
Valters IT
Senior DevSecOps & Cyber Threat Intelligence Expert