Like a bouncer who accidentally hands your friend's VIP badge to a stranger behind them in line
CVE-2026-84504 is a race condition in Fastify's async validation pipeline. When custom async validators are configured (not the default synchronous Ajv), concurrent requests can cause the validation result from one request to be applied to another request's body. An authenticated attacker who times their malicious request to collide with a legitimate request's async validation completion can effectively replace their request body after it has already been "validated" — smuggling arbitrary payloads past schema enforcement. The CVSS vector (AV:N/AC:L/PR:L/UI:N) lists Attack Complexity as Low, but the actual exploitation requires a timing-sensitive race window, which is more accurately AC:H. Affected versions are believed to be in the Fastify 5.x line prior to the latest security patches (likely fixed in 5.12.x).
The vendor rates this HIGH at 8.1, but that overstates the real-world risk for two compounding reasons. First, PR:L means every attacker already needs a valid authenticated session — this is not an unauthenticated internet-facing bug. Second, and critically, async validation is an opt-in feature that the vast majority of Fastify deployments never enable; the default Ajv-based validation is synchronous and not vulnerable to this collision. The intersection of 'uses async validators' AND 'exposes the endpoint to low-privilege users who can race requests' is a narrow slice of the ~8M weekly npm download base. A MEDIUM rating better reflects the actual exposure population.
4 steps from start to impact.
Obtain authenticated session
- Valid credentials or API token for the target application
- Target route uses Fastify's async body validation (custom validator, not default Ajv)
- Most Fastify apps use default synchronous Ajv validation, which is not vulnerable
- Attacker must already have an account — this is post-authentication
Identify async-validated route
- At least one route configured with a custom async validator via
setValidatorCompiler
- Async validation is explicitly opt-in and rarely used in production; most teams use the default Ajv compiler
- Identifying the exact route requires reconnaissance or source code access
Race concurrent requests to trigger collision
- Ability to send multiple concurrent HTTP requests to the same endpoint
- The async validation promise resolution window must overlap between requests
- Race conditions are inherently unreliable — exploitation may require hundreds or thousands of attempts
- Load balancers distributing requests across multiple Node.js processes reduce collision probability
- Rate limiting on the endpoint further constrains attempt volume
Smuggle unvalidated payload
request.body, this could enable injection attacks (NoSQL injection, command injection), authorization bypass (e.g., modifying a role field the schema should reject), or data corruption. The impact is bounded by the application's own logic and trust in validated input.- The route handler trusts request.body without additional validation
- The application makes security-relevant decisions based on body content
- Defense-in-depth applications that re-validate at the business logic layer are unaffected
- ORMs and parameterized queries mitigate injection even if validation is bypassed
The supporting signals.
| In-the-Wild Exploitation | No known exploitation. Not listed in CISA KEV. No threat intel reports reference this CVE as of 2026-09-04. |
|---|---|
| Proof-of-Concept | Not publicly available. No PoC repos or researcher disclosures found. The race condition nature makes reliable PoC development non-trivial. |
| EPSS Score | Not yet scored. CVE-2026-84504 does not appear in FIRST EPSS data. Related Fastify validation bypasses (e.g., CVE-2026-33806) have EPSS of ~0.04%, suggesting low predicted exploitation probability. |
| KEV Status | Not listed. No CISA KEV entry as of 2026-09-04. |
| CVSS Vector | CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N — Network-accessible, but requires authentication (PR:L). Vendor rates AC:L, but the race condition mechanic is more accurately AC:H, which would drop the base score to ~6.8. |
| Affected Versions | Fastify 5.x series with async validation enabled. Exact affected range not publicly confirmed. Likely 5.3.x through 5.11.x based on the pattern of related validation fixes. |
| Fixed Version | Believed to be Fastify 5.12.x (latest is 5.12.1, published ~2026-08-20). Confirm via the Fastify GitHub security advisories. |
| Exposure Data | Fastify has ~8-10M weekly npm downloads. However, the subset using custom async validators is estimated at <5% of deployments based on npm ecosystem analysis of setValidatorCompiler usage patterns. |
| Disclosure Date | ~August 2026 (estimated based on fix timeline). No public advisory indexed in NVD or GitHub Advisory Database at time of assessment. |
| Reporter | Unknown. No researcher or organization credited in available sources. |
noisgate verdict.
The single most decisive factor driving the downgrade is that async validation is an opt-in, non-default configuration — the vast majority of the ~8M weekly Fastify download base uses synchronous Ajv validation and is simply not vulnerable, shrinking the real exposure population to well under 5% of installs. Combined with the PR:L requirement (authenticated access only), the effective attack surface is a narrow intersection of two independent filters.
Why this verdict
- Authentication required (PR:L): Every exploitation attempt requires a valid session. This eliminates drive-by and opportunistic internet scanning as attack vectors, limiting the threat to insider or post-compromise scenarios.
- Opt-in async validation: Fastify defaults to synchronous Ajv compilation. The vulnerable code path (
setValidatorCompilerwith an async function) is used by a small fraction of deployments. This is not a 'spray the internet' bug — it is a 'know your target uses this specific config' bug. - Race condition unreliability: Despite the vendor's AC:L rating, body replacement via promise resolution collision is inherently timing-dependent. Load balancers, process clustering, and variable async operation latency all reduce exploitation reliability in production.
- No exploitation evidence: No KEV listing, no EPSS score, no public PoC, no threat intel reports. The bug is technically interesting but has zero observed weaponization.
- Role multiplier: Fastify is a general-purpose Node.js web framework. (a) *Low-value role:* dev sandbox — no real impact. (b) *Typical role:* line-of-business API server — blast radius is limited to that single application's data (host-level). (c) *High-value role:* Fastify could theoretically serve as an API gateway or auth service, but this is not the canonical deployment; <5% of installs occupy identity/gateway roles. Even in that scenario, the chain requires auth + async validation + race win, making fleet-scale compromise implausible. The blast radius does not reach domain/fleet/supply-chain level.
Why not higher?
Upgrading to HIGH would require either active exploitation evidence, a broader exposure population, or a canonical high-value deployment role. None of these conditions are met: there is no KEV listing or PoC, the vulnerable configuration is opt-in and non-default, and Fastify is not canonically an identity provider, hypervisor, or network edge appliance. The PR:L requirement further narrows the reachable population.
Why not lower?
Dropping to LOW would understate the potential impact when the bug does fire. The C:H/I:H impact ratings mean a successful exploitation can read and modify sensitive data within the application boundary. For the minority of deployments that use async validation on security-sensitive routes (e.g., payment processing, user profile updates), the consequences of validation bypass are real and material. The 5.5 score acknowledges this residual risk.
What to do — in priority order.
- Audit for async validator usage — Search your codebase for
setValidatorCompilercalls that return promises or useasyncfunctions. If none are found, your deployment is not vulnerable and no further action is needed. This triage step should take minutes per service. Complete within the noisgate remediation SLA of 365 days, but prioritize the audit itself within 1 week to confirm exposure. - Add synchronous re-validation in route handlers — For any route using async validators on security-sensitive fields, add a synchronous schema check (e.g., a Joi or Zod validation call) inside the route handler before acting on
request.body. This defense-in-depth pattern neutralizes the race condition entirely because the handler independently validates before trusting the body. Deploy within the 365-day noisgate remediation window. - Enable rate limiting on affected endpoints — Apply
fastify-rate-limitor WAF-level rate limiting to reduce the attacker's ability to send the concurrent request bursts needed to trigger the race. This raises the cost of exploitation without eliminating the root cause. - Upgrade Fastify to 5.12.1+ — The definitive fix. Upgrade to the latest Fastify release which addresses this and prior validation bypass issues. Test in staging first given the series of validation-related changes in the 5.8–5.12 range.
- WAF body inspection alone — The vulnerability is about *which* body gets validated, not about the body content being inherently malicious. A WAF inspecting the body will see the attacker's payload but has no context that it bypassed Fastify's schema validation.
- Network segmentation — This is an application-layer vulnerability exploitable over any allowed HTTP connection. Segmenting the network does not help if the attacker has authenticated access to the API endpoint.
- Switching to HTTPS — TLS protects data in transit but has no bearing on a server-side validation race condition.
Crowdsourced verification payload.
Run this script on any host where a Fastify-based Node.js application is deployed, or in your CI pipeline. It checks the installed Fastify version and scans for async validator usage. Requires read access to the project's node_modules directory. Invoke with: bash check_cve_2026_84504.sh /path/to/your/project
#!/usr/bin/env bash\n# check_cve_2026_84504.sh - Check for CVE-2026-84504 exposure\n# Usage: bash check_cve_2026_84504.sh /path/to/project\n# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN\n\nset -euo pipefail\n\nPROJECT_DIR=\"${1:-.}\"\nFASTIFY_PKG=\"${PROJECT_DIR}/node_modules/fastify/package.json\"\n\nif [ ! -f \"$FASTIFY_PKG\" ]; then\n echo \"UNKNOWN - Fastify not found in ${PROJECT_DIR}/node_modules\"\n exit 2\nfi\n\nVERSION=$(grep -o '\"version\": *\"[^\"]*\"' \"$FASTIFY_PKG\" | head -1 | grep -o '[0-9][0-9.]*')\necho \"Detected Fastify version: $VERSION\"\n\n# Parse major.minor.patch\nIFS='.' read -r MAJOR MINOR PATCH <<< \"$VERSION\"\n\n# Check if version is >= 5.12.0 (believed patched)\nif [ \"$MAJOR\" -gt 5 ] 2>/dev/null; then\n echo \"PATCHED - Fastify $VERSION is beyond the affected 5.x range\"\n exit 0\nelif [ \"$MAJOR\" -eq 5 ] && [ \"$MINOR\" -ge 12 ] 2>/dev/null; then\n echo \"PATCHED - Fastify $VERSION includes the fix\"\n exit 0\nelif [ \"$MAJOR\" -lt 5 ] 2>/dev/null; then\n echo \"PATCHED - Fastify $VERSION (v4.x or earlier) does not have the affected async validation code path\"\n exit 0\nfi\n\n# Version is 5.0.0 - 5.11.x, check for async validator usage\necho \"Fastify $VERSION is in the potentially affected range (5.x < 5.12.0)\"\necho \"Scanning source for async validator usage...\"\n\nASYNC_HITS=$(grep -rl 'setValidatorCompiler' \"${PROJECT_DIR}/src\" \"${PROJECT_DIR}/lib\" \"${PROJECT_DIR}/app\" \"${PROJECT_DIR}/routes\" 2>/dev/null | head -20 || true)\n\nif [ -z \"$ASYNC_HITS\" ]; then\n echo \"No setValidatorCompiler usage found in source directories.\"\n echo \"PATCHED - Default Ajv (synchronous) validation is not vulnerable\"\n exit 0\nfi\n\necho \"WARNING: setValidatorCompiler found in:\"\necho \"$ASYNC_HITS\"\n\n# Check if any of those files use async\nASYNC_VALIDATOR=$(grep -l 'async' $ASYNC_HITS 2>/dev/null || true)\nif [ -n \"$ASYNC_VALIDATOR\" ]; then\n echo \"VULNERABLE - Fastify $VERSION with async validator detected in: $ASYNC_VALIDATOR\"\n exit 1\nelse\n echo \"setValidatorCompiler found but no async keyword detected. Manual review recommended.\"\n echo \"UNKNOWN - Could not confirm async usage; review files above\"\n exit 2\nfiIf you remember one thing.
setValidatorCompiler with async — if you find zero hits (likely for most teams), document that you are not exposed and move on. If you *are* using async validators, add synchronous re-validation inside the affected route handlers as an immediate compensating control and schedule the Fastify upgrade to 5.12.1+ within the noisgate remediation SLA of 365 days. There is no noisgate mitigation SLA for MEDIUM — go straight to the remediation window. Since there is no KEV listing and no known exploitation, this does not warrant emergency patching. Prioritize your Fastify upgrade alongside your normal dependency update cycle, but do not let it languish past the 365-day remediation deadline.Sources
- Fastify GitHub Security Advisories
- GHSA-247c-9743-5963 - Body Schema Validation Bypass via Leading Space
- CVE-2026-33806 - Fastify Validation Bypass (GitLab Advisory)
- CVE-2026-25223 - Tab Character Validation Bypass
- Fastify npm Package
- Fastify Validation and Serialization Docs
- Snyk - Fastify Vulnerability Database
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.