# Nuxt, show me your payload - a basic CP DoS

Nuxt tests the full URL against the payload-route regex, so `?poc=/_payload.json` or `#/_payload.json` makes normal routes return payload JSON, enabling cache poisoning DoS.

- Payout: Research
- Severity: high
- Program: Nuxt
- Disclosed: 2025-03-03
- CVE: CVE-2025-27415
- Write-up quality: 7/10
- Original: https://zhero-web-sec.github.io/research-and-things/nuxt-show-me-your-payload
- Library page: https://bugbountylibrary.com/r/blog%3Azhero-web-sec-github-io-research-and-things-nuxt-show-me-your-payload
- Tags: area:web domain:web impact:dos kind:research platform:research sev:high tech:nodejs technique:source-review vuln:cache-poisoning vuln:dos vuln:misconfiguration

**Target:** Nuxt server rendering payload route /_payload.json
**Root cause:** The isRenderingPayload check runs a regex against the entire URL rather than the path, so a query string or fragment ending in /_payload.json satisfies it on any route.
**Steps:**
1. Read Nuxt source: isRenderingPayload = regex.test(url) matching /_payload.json or /_payload.js at end of string.
2. Request a normal route with `?poc=/_payload.json`; observe JSON payload returned instead of the page.
3. If URL params are excluded from cache key, request `https://www.example.com/?poc=/_payload.json` during cache-refresh window so it is cached for `https://www.example.com/`.
4. Alternative: send `#/_payload.json` through the proxy so the fragment is not part of the cache key; note some stacks encode it to %23 causing 404.
**How found:** Noticed the variable passed to regex.test() was named `url`, not path, hypothesizing the full URL was tested; confirmed by appending `?poc=/_payload.json` to a normal route and seeing the payload returned.
**Exploitation:** Attacker waits for cache expiry, sends a request to a normal route with `?poc=/_payload.json` (or `#/_payload.json`) so Nuxt returns the payload JSON with status 200; the CDN caches this response under the clean path, serving broken JSON to all subsequent visitors.
**Escalation:** Works on all Nuxt pages including those with empty payloads, widening the set of poisonable routes; hash variant bypasses the requirement that query params be excluded from the cache key.
**Insight:** When a framework regex-gates a special route, check whether it tests the full URL vs path — a query string or fragment ending in the magic suffix can flip the branch on any route, and fragments are invisible to cache keys.

## Proof of concept (copied exactly from the original report)

**Hash-based payload route bypass**

```
#/_payload.json through the proxy would achieve the same result
```

