CVE-2026-84504
Executive Summary
CVE-2026-84504 is an input validation flaw in the Fastify Node.js web framework (versions before 5.12.2) in which the framework confuses the object returned by a successful Ajv async validator with the internal "value result" protocol used by custom validator compilers. When a schema-validated request body contains a root-level property named value, Fastify replaces the entire request body with that property's contents before the route handler executes, meaning the handler processes an object that never satisfied the route schema. An authenticated low-privilege attacker can exploit this to smuggle unauthorized nested data past schema validation, triggering state-changing or data-disclosing operations the schema explicitly forbade. With a CVSS base score of 8.1 (High), the flaw warrants prompt patching for any organization running Fastify as an API or service backend.
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
Technical Analysis
Fastify uses Ajv as its JSON Schema validator and supports asynchronous validation. Internally, Fastify's validation pipeline has a convention — the "value result protocol" — by which a validator returns both a validity signal and a value that should be forwarded to subsequent processing; custom validator compilers rely on this protocol to communicate the canonical object to be used downstream. The vulnerability arises because Fastify, at versions before 5.12.2, cannot distinguish between:
- a legitimate value result emitted by a custom validator compiler, and
- a user-supplied property literally named
valuesitting at the root of a request body that has just passed schema validation.
Because the two are structurally identical from the framework's perspective, a body such as { "value": { ...arbitrary nested object... }, "otherValidatedField": "..." } is interpreted as "the validator wants the handler to receive the contents of value." Fastify therefore overwrites the validated request body with body.value before the handler runs. The consequence is that the handler operates on attacker-controlled nested data that was never evaluated against the route's JSON Schema constraints, while the schema only ever saw (and approved) the outer wrapper object.
This is a prototype/parsing-level confusion bug (CWE-20, Improper Input Validation) rather than a memory-safety issue. There is no code execution, no injection into the runtime, and no cross-tenant framework escape; the danger is purely the semantic gap between what the schema validated and what the handler received. The attack surface is every Fastify route that (a) has a request-body schema, (b) uses AJV with async validation or a custom validator compiler, and (c) passes the parsed body into a handler that assumes the body has been fully schema-checked. Because Fastify is commonly exposed directly to the internet as a REST/GraphQL backend, that attack surface is typically network-reachable (AV:N).
Notably, the flaw crosses the trust boundary that developers explicitly rely on when they write JSON Schemas: "if the request passed the schema, the handler can trust the shape of the data." That assumption is broken here. Schema-level guards such as additionalProperties: false, required, enum, and per-field type constraints can all be bypassed for the nested payload because the substituted object is never re-validated.
The CVSS vector (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N, base 8.1) reflects: network exploitation, low attack complexity, authenticated (low-privilege) requirement, no user interaction, unchanged scope, and High confidentiality and integrity impact with no direct availability impact. EPSS is 0.00399 (33.7th percentile), indicating that large-scale automated exploitation is not yet observed, though a public PoC exists and lowers the barrier to targeted abuse.
Exploitation Scenarios
No public PoC is available in the supplied data; the attack chain below is inferred strictly from the vulnerability class and the NVD description. No specific function names, endpoints, or parameters beyond the schema property value should be assumed.
Reconnaissance / target identification. The attacker enumerates a Fastify-backed API — typically exposed on ports 80/443/3000/8080 — and identifies routes protected by JSON Schema body validation. Endpoints that accept structured objects and expose state-changing operations (e.g., creating resources, updating a record, processing payments, or reading data scoped by an identifier) are primary targets. The attacker also needs at least low-privilege authenticated access; the flaw does not bypass authentication, only authorization-by-schema.
Triggering the flaw class. The attacker sends a schema-valid request body to a targeted route, but nests the intended malicious payload under a root property key named exactly
value. Because Fastify will replace the validated body with the contents ofvaluebefore the handler runs, the handler receives the attacker's nested object rather than the flat object that passed schema checks. The schema itself never sees the malicious nested structure, or sees it inside an opaque property it was not constraining.Payload / execution method (vulnerability-class level). The substituted object is then consumed by application logic that trusts the schema-approved shape. Field types, ranges,
requiredlists,enumvalues, andadditionalProperties: falseconstraints are all evaded for the submitted payload. If the handler forwards the body to an ORM, a downstream microservice, or a privileged action, the attacker's nested data becomes the effective input.Post-exploitation impact. Depending on what the route does, exploitation yields unauthorized state changes (a route that the schema was supposed to constrain now performs an operation the schema did not authorize) and disclosure of data the requester should not have received. Because the caller must already be authenticated, the practical impact is a privilege-separation failure: a low-privilege caller invokes a higher-privilege operation by smuggling a nested payload through the validator.
Field-validation caveat: because the description states that the entire request body is replaced by the contents of value, the attacker cannot rely on sibling fields surviving — only the value subtree is forwarded to the handler.
Impact Assessment
Business impact. Any service using a vulnerable Fastify version where route schemas are relied upon for authorization or data-shape enforcement is exposed. Because the substitution is silent and handler logic runs normally, the attack is unlikely to throw errors and may not be visible in application logs. The failure mode is an opaquely broken authorization boundary: routes that "validated" input can be made to execute operations the schema explicitly forbade, enabling unauthorized state changes and data disclosure — the two impact dimensions rated High in the CVSS vector.
Affected systems. Node.js services built on Fastify versions earlier than 5.12.2, especially those:
- exposing REST API routes reached over the network (AV:N),
- using JSON Schema body validation with AJV async validators, and
- making authorization or business-logic decisions based on the assumption that a schema-approved body is safe.
The framework itself is the affected component, so the blast radius is the application's entire schema-protected surface rather than a single endpoint.
Severity context. CVSS 8.1 (High). Confidentiality: High (C:H) — smuggled payloads can force disclosure of data the caller was not authorized to obtain. Integrity: High (I:H) — attacker-controlled nested data drives unauthorized state changes. Availability: None (A:N). The PR:L subscore means authentication is required, but no special privilege is needed; S:U indicates the impact stays within the vulnerable Fastify component's security scope. EPSS 0.00399 and no CISA KEV listing mean exploitation is not yet at scale, but the public PoC status raises the likelihood over time.
Detection Guidance
Sigma Rule
title: Fastify Ajv Validator "value" Property Body-Substitution Exploitation (CVE-2026-84504)
id: 9f3a1c7e-4b2d-4a88-9e31-6c0f5d8a1b2e
status: experimental
description: Detects requests to Fastify routes where a root-level "value" property is present in a JSON body, indicating attempts to exploit CVE-2026-84504 body substitution via the Ajv value-result protocol.
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-84504
author: Threat Intelligence Team
date: 2026/01/01
tags:
- attack.initial-access
- attack.t1190
- cve.2026.84504
logsource:
category: webserver
product: fastify
detection:
selection_method:
cs-method: 'POST'
selection_body:
cs-body|contains: '"value"'
condition: selection_method and selection_body
falsepositives:
- Legitimate APIs that intentionally accept a top-level "value" field
- Generic JSON payloads containing a "value" key for non-Fastify routes
level: medium
YARA Rule
rule CVE_2026_84504_Fastify_Value_Substitution
{
meta:
author = "Threat Intelligence Team"
description = "Detects HTTP request bodies attempting the Fastify Ajv value-result protocol confusion (CVE-2026-84504)"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2026-84504"
date = "2026-01-01"
severity = "high"
strings:
$body_marker = "\"value\":" nocase ascii
$method_post = "POST " ascii
$ct_json = "application/json" nocase ascii
condition:
$ct_json and $body_marker and $method_post
}
Suricata IDS Rule
alert http any any -> any any (msg:"CVE-2026-84504 Fastify Ajv 'value' Body Substitution Attempt"; flow:established,to_server; http.method; content:"POST"; http.request_body; content:"\"value\""; nocase; http.content_type; content:"application/json"; nocase; classtype:attempted-user; reference:cve,2026-84504; reference:url,nvd.nist.gov/vuln/detail/CVE-2026-84504; sid:202684504; rev:1;)
Elastic Detection
sequence by source.ip with maxspan=1m
[network where network.protocol == "http" and http.request.method == "POST" and
http.request.body.content : "\"value\"" and
http.request.mime_type : "application/json"]
Splunk SPL Query
index=web sourcetype=fastify_access OR sourcetype=*http*
| eval body = coalesce(http_request_body, request_body, body)
| eval ct = coalesce(content_type, mime_type)
| where match(method, "(?i)POST|PUT|PATCH")
| where like(ct, "%application/json%")
| where match(body, "\"value\"\s*:")
| stats count min(_time) as first_seen max(_time) as last_seen values(uri_path) as targets by src_ip
| where count >= 3
| sort - count
Wazuh OSSEC Rule
<group name="fastify,cve-2026-84504,">
<rule id="2026845" level="10">
<decoded_as>json</decoded_as>
<field name="http.request.method">POST|PUT|PATCH</field>
<field name="http.request.mime_type">application/json</field>
<field name="http.request.body.content">\"value\"</field>
<description>CVE-2026-84504: Possible Fastify Ajv 'value' property body-substitution attempt</description>
<mitre>
<id>T1190</id>
</mitre>
<group>cve_2026_84504,attack.initial_access,</group>
</rule>
</group>
Mitigation & Patch Guidance
Patch confidence: 3/4 (LIKELY). Two independent sources (NVD and OSV) confirm the fix version as fastify 5.12.2. No vendor advisory or workaround is listed in the supplied data.
Immediate mitigations (if patching is delayed).
- Inventory all Fastify deployments and confirm the resolved version (
npm ls fastify/ lockfile inspection). Any service on< 5.12.2is affected. - Reject request bodies containing a root-level
valueproperty at the edge/reverse proxy for routes that do not intentionally use it. - Do not rely on JSON Schema body validation as an authorization control for the duration of exposure. Where a body property is security-relevant (e.g., account ID, role, amount), re-validate it inside the handler against server-side state rather than trusting that it satisfied the schema.
- Reduce unnecessary exposed Fastify endpoints and ensure low-privilege accounts cannot reach state-changing routes they do not need.
- Given a public PoC exists, raise monitoring priority and enable the detection rules above.
- Inventory all Fastify deployments and confirm the resolved version (
Patch / upgrade steps.
- Upgrade Fastify to 5.12.2 or later.
- Regenerate lockfiles (
npm install fastify@latest, commitpackage-lock.json), then rebuild and redeploy container images. - Audit transitive dependency trees for pinned or vendored Fastify versions in monorepos and internal frameworks.
- Re-run integration tests against schema-validated routes and add regression tests asserting that a root
valueproperty in a request body is not substituted into the handler payload.
Long-term hardening.
- Treat schema validation and authorization as separate layers: never let "passed the schema" imply "authorized."
- Enable
additionalProperties: falseand strict schemas on all body-carrying routes as defense-in-depth (recognizing that CVE-2026-84504 shows schema constraints alone were insufficient here). - Subscribe to the Fastify security advisories and OSV feeds; integrate
npm audit/ OSV-Scanner into CI. - Enforce structured request logging (method, path, content-type, body hash) to make silent-substitution behavior auditable.
References
- NVD — CVE-2026-84504: https://nvd.nist.gov/vuln/detail/CVE-2026-84504
- OSV — Fastify advisory (CVE-2026-84504): https://osv.dev/vulnerability/CVE-2026-84504
- Fastify releases (patch version 5.12.2): https://github.com/fastify/fastify/releases
- MITRE ATT&CK T1190 — Exploit Public-Facing Application: https://attack.mitre.org/techniques/T1190/
- CWE-20 — Improper Input Validation: https://cwe.mitre.org/data/definitions/20.html
Threat-actor / exploit-in-the-wild status: No CISA KEV listing; no exploit code in-the-wild reported. A public PoC is noted. EPSS 0.00399 (33.7th percentile) indicates low-but-nonzero predicted exploitation activity. No named threat actor campaigns have been attributed to this CVE in the supplied data.
What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.