Where
-Infinity
0
Severity
8.8
CSRF
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H

Fastify is a web framework with minimal overhead and plugin architecture. The attacker can use the incorrect Content-Type to bypass the Pre-Flight checking of fetch. fetch() requests with Content-Type’s essence as "application/x-www-form-urlencoded", "multipart/form-data", or "text/plain", could potentially be used to invoke routes that only accepts application/json content type, thus bypassing any CORS protection, and therefore they could lead to a Cross-Site Request Forgery attack. This issue has been patched in version 4.10.2 and 3.29.4. As a workaround, implement Cross-Site Request Forgery protection using @fastify/csrf'.

First published (updated )
Severity
8.1
Input Validation
AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N

fastify versions before 5.12.2 treat the object resolved by a successful Ajv async validator as the value result protocol used by custom validator compilers. If a request that passes its route schema contains a property named value at the root, fastify replaces the entire request body with that property's value before the handler runs, so the handler receives a different object than the one that satisfied the schema. An authenticated low-privilege caller can use this to make nested data replace the validated body and trigger an operation the route schema did not authorize, leading to unauthorized state changes and data disclosure. Users should upgrade to fastify 5.12.2 or later.

First published (updated )
Severity
7.5
EPSS
0.06%
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N

Impact

In applications that specify different validation strategies for different content types, it's possible to bypass the validation by providing a slightly altered content type such as with different casing or altered whitespacing before ;.

Users using the the following pattern are affected:

js fastify.post('/', { handler(request, reply) { reply.code(200).send(request.body) }, schema: { body: { content: { 'application/json': { schema: { type: 'object', properties: { 'foo': { type: 'string', } }, required: ['foo'] } }, } } } })

User using the following pattern are not affected:

js fastify.post('/', { handler(request, reply) { reply.code(200).send(request.body) }, schema: { body: { type: 'object', properties: { 'foo': { type: 'string', } }, required: ['foo'] } } })

Patches

This was patched in v5.3.1, but unfortunately it did not cover all problems. This has been fully patched in v5.3.2. Version v4.9.0 was also affected by this issue. This has been fully patched in v4.9.1.

Workarounds

Do not specify multiple content types in the schema.

References Are there any links users can visit to find out more?

https://hackerone.com/reports/3087928

1 / 2
Source: GitHub
First published (updated )
Severity
7.5
EPSS
0.02%
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N

Impact

A validation bypass vulnerability exists in Fastify where request body validation schemas specified by Content-Type can be completely circumvented. By appending a tab character (\t) followed by arbitrary content to the Content-Type header, attackers can bypass body validation while the server still processes the body as the original content type.

For example, a request with Content-Type: application/json\ta will bypass JSON schema validation but still be parsed as JSON.

This vulnerability affects all Fastify users who rely on Content-Type-based body validation schemas to enforce data integrity or security constraints. The concrete impact depends on the handler implementation and the level of trust placed in the validated request body, but at the library level, this allows complete bypass of body validation for any handler using Content-Type-discriminated schemas.

This issue is a regression or missed edge case from the fix for a previously reported vulnerability.

Patches

This vulnerability has been patched in Fastify v5.7.2. All users should upgrade to this version or later immediately.

Workarounds

If upgrading is not immediately possible, user can implement a custom onRequest hook to reject requests containing tab characters in the Content-Type header:

javascript fastify.addHook('onRequest', async (request, reply) => { const contentType = request.headers['content-type'] if (contentType && contentType.includes('\t')) { reply.code(400).send({ error: 'Invalid Content-Type header' }) } })

Resources

- https://github.com/fastify/fastify/blob/759e9787b5669abf953068e42a17bffba7521348/lib/validation.js#L272 - https://github.com/fastify/fastify/blob/759e9787b5669abf953068e42a17bffba7521348/lib/content-type-parser.js#L125 - Fastify Validation and Serialization Documentation - https://hackerone.com/reports/3464114

1 / 2
Source: GitHub
First published (updated )
Severity
7.5
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N

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: js 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:

js 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

js 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 FSTERRVALIDATION

// 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: js function getEssenceMediaType(header) { if (!header) return '' return header.trimStart().split(/[ ;]/, 1)[0].trim().toLowerCase() }

1 / 2
Source: GitHub
First published (updated )
Severity
7.5
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N

fastify versions >= 4.0.0 and before 5.12.2 can route a malformed URL sent under one plugin prefix to the custom not-found handler of a different sibling plugin, and invoke it without the preHandler hook declared for that handler. The internal not-found router for encapsulated handlers dispatches malformed paths through a single shared handler pointer before URL decoding, ignoring the prefix and skipping the selected handler's normal lifecycle. An unauthenticated attacker can therefore reach an authentication-protected private fallback through an unrelated public prefix and read its full response, bypassing the authentication hook and breaking prefix encapsulation. Users should upgrade to fastify 5.12.2 or later.

First published (updated )
Severity
7.5
Input Validation
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N

fastify versions before 5.12.2 decide whether to compile a request schema based on JavaScript truthiness, but JSON Schema Draft 7 defines the boolean false as a valid schema that rejects every instance. When an application assigns false to a route's body, querystring, params, or headers schema to deny all input, fastify treats it as a missing schema, compiles no validator, and runs the route handler on any request. An unauthenticated remote client can therefore reach a handler that a valid deny-all schema was intended to make unreachable, a complete validation bypass that can lead to unauthorized state changes or execution of disabled operations. Users should upgrade to fastify 5.12.2 or later.

First published (updated )
Severity
7.5
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N

fastify versions before 5.12.2 implement the case-insensitive nature of HTTP header names by lowercasing names in a route's header schema before compiling it, but the transformation is incomplete: it lowercases the properties keys and the root-level required array, and does not lowercase the trigger and dependent names inside the JSON Schema Draft 7 dependencies keyword. Because Node stores request header names in lowercase, a canonical-case dependency such as requiring an authentication header whenever a privileged-mode header is present never matches, and the presence assertion is silently skipped. An unauthenticated remote client can therefore send the header that activates a privileged branch while omitting the header the dependency was meant to require, bypassing the conditional check. Users should upgrade to fastify 5.12.2 or later.

First published (updated )
Severity
7.5
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

Fastify node module before 0.38.0 is vulnerable to a denial-of-service attack by sending a request with "Content-Type: application/json" and a very large payload.

First published (updated )
Severity
6.5
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H

A denial of service vulnerability exists in Fastify v2.14.1 and v3.0.0-rc.4 that allows a malicious user to trigger resource exhaustion (when the allErrors option is used) with specially crafted schemas.

First published (updated )
Severity
6.1
EPSS
0.01%
CSRF
AV:A/AC:H/PR:N/UI:N/S:C/C:H/I:N/A:N

Summary

When trustProxy is configured with a restrictive trust function (e.g., a specific IP like trustProxy: '10.0.0.1', a subnet, a hop count, or a custom function), the request.protocol and request.host getters read X-Forwarded-Proto and X-Forwarded-Host headers from any connection — including connections from untrusted IPs. This allows an attacker connecting directly to Fastify (bypassing the proxy) to spoof both the protocol and host seen by the application.

Affected Versions

fastify <= 5.8.2

Impact

Applications using request.protocol or request.host for security decisions (HTTPS enforcement, secure cookie flags, CSRF origin checks, URL construction, host-based routing) are affected when trustProxy is configured with a restrictive trust function.

When trustProxy: true (trust everything), both host and protocol trust all forwarded headers — this is expected behavior. The vulnerability only manifests with restrictive trust configurations.

1 / 2
Source: GitHub
First published (updated )
Severity
6.1
CSRF
AV:A/AC:H/PR:N/UI:N/S:C/C:H/I:N/A:N

Impact

The fix for CVE-2026-3635 (GHSA-444r-cwp2-x5xf) added a proxyFn(socket.remoteAddress, 0) guard on the X-Forwarded- reads in request.host, request.protocol, request.hostname, request.ip, and request.ips. That guard closes the IP, CIDR, and custom-function forms of trustProxy correctly because those forms compile to predicates that inspect the connecting address. The hop-count form (trustProxy: <number>) compiles to a predicate that structurally ignores the address argument, so the guard reduces to 0 < tp, always true for any tp >= 1.

Applications configured with trustProxy: <number> (documented as "behind N reverse proxies", trustProxy: 1 being the canonical single-proxy setting) remain vulnerable. An attacker who can reach the Fastify origin directly, bypassing the front-facing proxy, can spoof the request fields exactly as in the unpatched version. Impact class matches the parent CVE-2026-3635: host injection in generated URLs, HTTPS-enforcement bypass, secure-cookie / CSRF-origin bypass, host-based routing and cache poisoning.

Patches

Patched in fastify 5.12.1. The numeric form of trustProxy is now disabled at runtime and removed from the TypeScript type union.

Workarounds

- Migrate to an IP / CIDR / custom-function trustProxy value that validates the connecting address. Custom functions must inspect the address argument, not only the hop index. - Ensure the Fastify origin is only reachable through the trusted proxy chain (no direct network path).

1 / 2
Source: GitHub
First published (updated )
Severity
5.4
Input Validation
AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N

Impact

fastify before 5.12.1, when a route uses a root-level primitive body schema (for example an integer with a minimum and maximum) and the default type coercion, validates the coerced value but exposes the original, uncoerced value to the route handler. For example, a JSON body "10" is coerced to the number 10 and passes an integer 1 to 10 schema, but request.body stays the string "10". An application that trusts the validated type is handed a value that did not satisfy the schema, which can bypass limits the application enforces on that typed value. Object and array body schemas are not affected, they coerce their members in place.

Patches

Upgrade to fastify 5.12.1.

Workarounds

Until you can upgrade, avoid relying on the validated type of a root primitive body. Wrap the value in an object schema (object properties are coerced in place), for example accept { "value": 10 } and read request.body.value, or re-check the type in the handler.

1 / 2
Source: GitHub
First published (updated )
Severity
5.3
EPSS
0.01%
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N

Description

Fastify incorrectly accepts malformed Content-Type headers containing trailing characters after the subtype token, in violation of RFC 9110 §8.3.1. For example, a request sent with Content-Type: application/json garbage passes validation and is processed normally, rather than being rejected with 415 Unsupported Media Type.

When regex-based content-type parsers are in use (a documented Fastify feature), the malformed value is matched against registered parsers using the full string including the trailing garbage. This means a request with an invalid content-type may be routed to and processed by a parser it should never have reached.

Impact

An attacker can send requests with RFC-invalid Content-Type headers that bypass validity checks, reach content-type parser matching, and be processed by the server. Requests that should be rejected at the validation stage are instead handled as if the content-type were valid.

Workarounds

Deploy a WAF rule to protect against this

Fix

The fix is available starting with v5.8.1.

1 / 2
Source: GitHub
First published (updated )
Severity
3.7
EPSS
0.01%
AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L

Impact A Denial of Service vulnerability in Fastify’s Web Streams response handling can allow a remote client to exhaust server memory. Applications that return a ReadableStream (or Response with a Web Stream body) via reply.send() are impacted. A slow or non-reading client can trigger unbounded buffering when backpressure is ignored, leading to process crashes or severe degradation.

Patches The issue is fixed in Fastify 5.7.3. Users should upgrade to 5.7.3 or later.

Workarounds Avoid sending Web Streams from Fastify responses (e.g., ReadableStream or Response bodies). Use Node.js streams (stream.Readable) or buffered payloads instead until the project can upgrade.

References - https://hackerone.com/reports/3524779

1 / 2
Source: GitHub
First published (updated )

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203