Mar 6, 2026·4 min read·3 visits
Fastify versions prior to 5.8.1 incorrectly validate `Content-Type` headers due to a missing regex anchor. Attackers can append arbitrary garbage to media types (e.g., `application/json<script>`) to bypass validation logic while still triggering JSON parsing.
Fastify, a high-performance web framework for Node.js, contains a validation bypass vulnerability in its `Content-Type` header parsing logic. Due to an incomplete regular expression in `lib/content-type.js`, the framework fails to enforce the end-of-string anchor (`$`) when validating media subtypes. This omission allows attackers to supply malformed `Content-Type` headers containing illegal trailing characters (e.g., `application/json garbage`), which Fastify incorrectly accepts as valid. This behavior violates RFC 9110 §8.3.1 and can lead to parser confusion where malicious payloads are routed to incorrect content parsers, potentially bypassing security controls or triggering unexpected application behavior.
CVE-2026-3419 identifies a medium-severity validation flaw in the Fastify web framework's handling of HTTP Content-Type headers. The vulnerability resides in the core library's MIME type parsing mechanism, specifically where it validates the subtype portion of a media type (the json in application/json).
Under RFC 9110, a media type must conform to strict syntax rules, essentially type/subtype. Fastify attempts to validate this structure using regular expressions. However, the regex used for the subtype validation failed to assert the end of the input string. Consequently, the parser performs a prefix match rather than an exact match.
This flaw allows a client to send a header like Content-Type: application/json unknown-suffix. While a strictly compliant server would reject this as an invalid media type (returning HTTP 415), vulnerable versions of Fastify validate the json prefix and accept the header. This discrepancy permits malformed requests to proceed to the body parsing stage, potentially confusing downstream logic or logging systems that expect RFC-compliant headers.
The root cause is a classic Regular Expression Anchoring error (CWE-185) located in lib/content-type.js. The regular expression subtypeNameReg was designed to validate that the subtype consists only of allowed characters (alphanumerics and specific symbols like !#$%&'*+.^|~-`).
The vulnerable definition was:
const subtypeNameReg = /^[\w!#$%&'*+.^`|~-]+\s*/This regex uses the start-of-string anchor (^) but omits the end-of-string anchor ($). In JavaScript's RegExp engine, this instructs the matcher to verify that the string starts with valid characters, but it does not constrain what follows those characters. If the input is json garbage, the engine matches json against the allowed character class and considers the pattern satisfied, ignoring the trailing garbage.
Correct validation requires ensuring the entire string matches the allowed pattern. By missing the $, Fastify effectively downgraded its validation from "is exactly this format" to "starts with this format," opening the door for arbitrary suffix injection.
The remediation involves a single-character change to the regular expression in lib/content-type.js. The patch enforces strict equality by appending the $ anchor, ensuring the regex matches the full string length.
Below is the comparison of the vulnerable and patched code:
// Vulnerable Code (lib/content-type.js)
// The regex matches any string starting with valid subtype characters.
// Input "json malicious" -> MATCH (Vulnerable)
const subtypeNameReg = /^[\w!#$%&'*+.^`|~-]+\s*/
// Patched Code (Fixed in v5.8.1)
// The '$' anchor ensures the string ends immediately after the valid characters.
// Input "json malicious" -> NO MATCH (Secure)
const subtypeNameReg = /^[\w!#$%&'*+.^`|~-]+\s*$/When subtypeNameReg.test(subtype) is called in the fixed version, the engine consumes the valid characters and then checks for the end of the string. If unauthorized characters (like spaces followed by text, or control characters) are present, the match fails, and Fastify correctly identifies the media type as invalid.
Exploitation of this vulnerability requires an attacker to send HTTP requests with crafted Content-Type headers. The primary goal is to bypass strict validation checks while still triggering a specific content parser (usually the JSON parser).
Attack Scenario: Parser Confusion
application/json. It may have security middleware that blocks requests with unknown content types but uses the same loose validation logic.Content-Type: application/json; boundary=exploit (syntactically incorrect for JSON) or Content-Type: application/json<script>.application/json because of the prefix match. The request is routed to the JSON parser.This behavior is particularly risky if the application relies on the Content-Type header for security decisions (e.g., "only allow strictly application/json") or if the malformed header bypasses a WAF rule that expects strict RFC compliance but the application accepts it, creating a differential allowing the payload through.
The impact of CVE-2026-3419 is classified as Medium (CVSS 5.3). While it does not directly allow Remote Code Execution (RCE) or SQL Injection, it compromises the integrity of the input validation layer.
Technical Impact Breakdown:
application/x-www-form-urlencoded to prevent parameter pollution, but if an attacker sends application/json payload, and the server parses it as form data due to a misconfiguration or fallback, the protection is bypassed.application/json\x00garbage) may corrupt logs or mislead analysts reviewing traffic logs.CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
Fastify OpenJS Foundation | < 5.8.1 | 5.8.1 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-185 |
| CWE Name | Incorrect Regular Expression |
| CVSS v3.1 | 5.3 (Medium) |
| Attack Vector | Network |
| Impact | Validation Bypass |
| Status | Patched |
The software uses a regular expression that contains an error, or the regex does not correctly adhere to the intended logic, leading to inaccurate matches.