CVE-2026-18427
Executive Summary
CVE-2026-18427 is a high-severity path traversal vulnerability (CWE-22) affecting the @fastify/static middleware for the Fastify web framework. Versions prior to 10.1.3 contain an incomplete fix for a previously disclosed route guard bypass, allowing unauthenticated attackers to retrieve files protected by route-based access guards by leveraging non-canonical path segments such as encoded dots, duplicate slashes, or backslashes. The vulnerability carries a CVSS score of 7.5 (High) with a vector of CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N, indicating full network accessibility, no privileges required, no user interaction, and a high confidentiality impact. Applications that protect a subtree of the static root using route-based guards are vulnerable; applications using the allowedPath option are not affected.
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
The root cause of CVE-2026-18427 lies in the interaction between Fastify's routing layer and the @fastify/static plugin's path handling logic. The vulnerability represents an incomplete patch — an earlier guard that was intended to prevent path traversal was insufficiently strict, and the bypass mechanism was not fully closed.
When Fastify receives an HTTP request, it parses the URL and performs route matching. Route-based guards in Fastify rely on matching the request pathname against a pattern. However, the URL path may contain several non-canonical forms that are normalized differently by the routing engine versus the filesystem access layer:
Dot segments (
./,../): The earlier fix rejected only literal parent directory sequences (..), but did not account for the fact that many HTTP clients and intermediaries normalize dot segments before the request reaches the server. If the server's routing layer receives a path like/guard/../protected/file, the guard pattern may not match, but the filesystem access layer resolves the path back to the protected file.Encoded dots (
%2e): URL-encoded forms such as%2e%2e%2f(encoded../) are not decoded consistently between routing and file serving. The route guard sees the encoded characters and fails to match; thesendlayer decodes them and resolves the traversal.Duplicate slashes (
//): Multiple consecutive forward slashes are not collapsed during routing. A request like/guard//protected/filemay match the static file handler but bypass the guard pattern that expects a single slash.Backslashes (
\): On Windows-like filesystems (or where the path is resolved with backslash as a separator), backslashes are treated as path separators during file resolution but not during URL route matching. A request like/guard\..\..\protected/filecould bypass the guard while still resolving to the protected file.
The core issue is that the @fastify/static plugin delegated the file resolution to the send layer without first canonicalizing the pathname. The fix in version 10.1.3 canonicalizes the pathname — collapsing dot segments, normalizing duplicate slashes, decoding encoded characters, and rejecting backslashes — before using the path for both routing and file serving.
The attack surface is the network-facing HTTP interface of Fastify applications that use @fastify/static to serve static files from a directory that contains a mixture of public and protected content, where protected content is guarded by a route-level check (e.g., authentication or authorization middleware). This is a common pattern for serving user uploads, private documents, or configuration files alongside publicly accessible assets.
Exploitation Scenarios
The following is a concrete attack chain. No public exploit code exists at the time of writing, but the vulnerability class is well-understood and trivially exploitable with standard HTTP tools (e.g., curl).
Step 1 — Reconnaissance/Target Identification:
An attacker identifies a Fastify application using @fastify/static. This may be detected by:
- Observing typical Fastify response headers (e.g.,
Server: Fastify) or error signatures. - Probing for common static file paths (
/public/,/static/,/assets/) and verifying the server returns static file content. - Using search engine dorks or HTTP fingerprinting to find Fastify applications with static file serving enabled.
The attacker then maps the application's route structure by:
- Requesting known paths and observing 200 vs 403/404 responses.
- Analyzing JavaScript files for API endpoints or file references.
- Looking for publicly visible directories that indicate a static root (e.g.,
/uploads/).
Step 2 — Trigger/Weaponization:
The attacker crafts a malicious path that bypasses the route guard. Assume the application serves static files from /var/www/static/ and protects the /private/ subtree with an authentication guard. The attacker sends a request such as:
GET /public/../private/secret-api-keys.txt HTTP/1.1
Host: victim.com
Normally, the route guard would match /private/* and deny access. However, because the router matches the literal path string /public/../private/secret-api-keys.txt, the guard pattern does not fire, and the request is routed to the static file handler. The handler then resolves the path using the filesystem, normalizing the ../ segment and serving /private/secret-api-keys.txt.
Alternatively, the attacker uses encoded variants:
GET /public/%2e%2e/private/sensitive.pdf HTTP/1.1
Or backslash variants (if the server runs on Windows or the send library normalizes backslashes):
GET /public\..\private\sensitive.pdf HTTP/1.1
Or duplicate slash variants:
GET /public//../private/sensitive.pdf HTTP/1.1
Step 3 — Payload/Execution: The attacker iterates over candidate protected filenames, commonly:
- Configuration files (
.env,config.json,database.yml) - Private documents (PDFs, spreadsheets, archives)
- Source code snapshots (
*.tar.gz,*.zip) - Backup files (
*.bak,*.old)
If the application is single-threaded and does not rate-limit, the attacker can script an automated loop to enumerate the protected directory structure using traversal chains.
Step 4 — Post-Exploitation Impact:
- If secrets (API keys, database credentials) are disclosed, the attacker can pivot to other systems — cloud accounts, databases, internal APIs.
- If the exposed file contains user PII, the attacker can conduct targeted fraud, phishing, or extortion.
- If source code is exposed, the attacker gains deep knowledge of the application logic, enabling further targeted attacks (e.g., identifying additional vulnerabilities, finding hardcoded secrets).
- The attacker may also map the filesystem structure to identify additional sensitive data or persistence mechanisms (e.g., credential files for the service account).
Impact Assessment
The CVSS score of 7.5 (High) reflects a vulnerability that is trivially exploitable over the network without authentication and with no user interaction. The confidentiality impact is rated HIGH (C: H), meaning full disclosure of file contents is possible. Integrity and availability are unaffected (I: N, A: N).
Business Impact:
- Confidentiality Breach: Arbitrary file disclosure can expose trade secrets, customer data, intellectual property, and operational credentials.
- Regulatory Exposure: If PII is involved, the organization may face GDPR, HIPAA, or PCI-DSS violations with potential fines.
- Downstream Compromise: Disclosed credentials or application secrets can enable lateral movement, account takeover, and supply chain attacks.
- Reputation Damage: Public disclosure of a data breach erodes customer trust and can impact share price.
Affected Systems:
- All Fastify applications using
@fastify/staticbefore version 10.1.3. - Applications where
@fastify/staticis used with route-based access guards (e.g.,preHandleroronRequesthooks that check the URL pattern). - Applications that explicitly protect a subtree (e.g.,
/private/,/admin/,/uploads/private/) are in scope. Applications relying solely on theallowedPathoption are not vulnerable.
Blast Radius:
- Any file within or beneath the static root directory.
- Files outside the root via deep traversal chains (depending on the OS and the
sendlibrary's normalization behavior). - Indirect exposure of databases, cloud credentials, and internal network topology via disclosed configuration files.
Given the incomplete-fix nature, any organization that applied the prior patch but has not yet upgraded to 10.1.3 retains a false sense of security and remains exposed.
Detection Guidance
The following detection artifacts focus on identifying attempts to exploit the non-canonical path traversal behavior. They target both proxy-level (network) and server-level (logs/endpoint) detection.
Sigma Rule
title: Fastify Static Route Guard Bypass via Non-Canonical Paths
id: 9f6b2c47-36dd-4a3b-9ea5-b4ec29c9f6d1
status: experimental
description: Detects HTTP requests with non-canonical path segments attempting to bypass route guards in @fastify/static.
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-18427
author: Valters IT Threat Intelligence Team
date: 2026/01/15
logsource:
category: webserver
product: fastify
detection:
selection_dot_segments:
cs-uri-query|contains:
- '/../'
- '/..%2f'
- '/%2e%2e/'
- '/%2e%2e%2f'
selection_encoded_dots:
cs-uri-query|contains:
- '%2e'
- '%2E'
selection_duplicate_slashes:
cs-uri-query|contains:
- '//'
selection_backslashes:
cs-uri-query|contains:
- '\\'
selection_mixed:
cs-uri-query|contains:
- '/..\\'
- '/%2e%2e\\'
condition: selection_dot_segments or selection_encoded_dots or selection_duplicate_slashes or selection_backslashes or selection_mixed
filter_known_log4j:
cs-uri-query|contains: '${'
falsepositives:
- Legitimate URLs with encoded characters in file names (rare but possible)
- Backslash characters in query parameters for non-file-serving endpoints
level: high
tags:
- attack.t1190
- cve.2026-18427
- cwe.22
YARA Rule
rule Fastify_Static_Route_Guard_Bypass_CVE_2026_18427
{
meta:
author = "Valters IT Threat Intelligence Team"
date = "2026-01-15"
description = "Detects suspicious HTTP paths attempting to exploit CVE-2026-18427"
cve = "CVE-2026-18427"
severity = "high"
strings:
$traversal_plain = "/../"
$traversal_encoded_1 = "/%2e%2e"
$traversal_encoded_2 = "/%2E%2E"
$traversal_mixed_1 = "/..%2f"
$traversal_mixed_2 = "/%2e%2e%2f"
$backslash = "\\"
$double_slash = "//"
condition:
filesize < 10KB and
(
any of ($traversal_*) or
(
$backslash at 0 // quick check — refine with context if needed
)
) and
#double_slash > 0
}
Suricata IDS Rule
alert http any any -> $HOME_NET any (
msg:"CVE-2026-18427 - Fastify Static Route Guard Bypass Attempt";
flow:to_server,established;
http.uri;
content:"/../";
http.uri;
content:"%2e%2e";
pcre:"/(?:%2e%2e(?:\/|%2f)|\.\.(?:\/|%2f|\\|%5c))/i";
classtype:attempted-recon;
reference:cve,2026-18427;
reference:url,nvd.nist.gov/vuln/detail/CVE-2026-18427;
sid:20260184;
rev:1;
metadata:created_at 2026_01_15, updated_at 2026_01_15;
)
Elastic Detection
sequence by source.ip with maxspan=5m
[ any where process.name == "node" and event.module == "fastify" ]
[ any where http.request.uri == "*"
and (
string(http.request.uri) like "/../" or
string(http.request.uri) like "/%2e%2e" or
string(http.request.uri) like "\\" or
string(http.request.uri) like "//"
)
]
[ any where http.response.status_code == 200 and http.response.body.bytes > 0 ]
Splunk SPL Query
index=weblog sourcetype=access_combined
| eval uri_lower = lower(uri)
| search uri_lower IN (
"*%2e%2e*",
"*%2e%2e%2f*",
"*..%2f*",
"*..\\\\*",
"*\\\\..*",
"*//*",
"/../"
)
| stats count by uri, src_ip, status, method, _time
| where count > 1
| table _time, src_ip, method, uri, status, count
| sort - count
Wazuh OSSEC Rule
<rule id="100842" level="15">
<decoded_as>json</decoded_as>
<field name="url" type="pcre2">(?:/%2e%2e|/\.\./|/\.\.%5c|\\\\|//)</field>
<description>CVE-2026-18427 - Fastify static route guard bypass attempt detected</description>
<group>web_attack,pci_dss_6.5.1,gdpr_32,</group>
<mitre>
<id>T1190</id>
</mitre>
<options>no_full_log</options>
<regex>\.\.|%2e|\\\\</regex>
<var name="srcip">$srcip</var>
<field name="http.response.code" type="pcre2">^[45]\d\d$</field>
<info>Source IP $srcip attempted path traversal against Fastify static handler. URI: $url. Status: $http.response.code</info>
</rule>
Mitigation & Patch Guidance
Patch Confidence: 2/4 (CLAIMED — single source claims patch — not independently confirmed).
The NVD advisory states the vulnerability is fixed in @fastify/static version 10.1.3. However, this claim originates from a single source (NVD) and has not been independently confirmed by release notes, changelogs, or vendor advisories. Despite the reduced confidence, the recommended action is to upgrade, but verify the version and behavior after deployment.
1. Immediate Mitigations (do these NOW)
- Upgrade to
@fastify/staticversion 10.1.3 or later. Use the Node.js package manager for your environment:npm install @fastify/static@^10.1.3 # or yarn add @fastify/static@^10.1.3 # or pnpm add @fastify/static@^10.1.3 - If you cannot upgrade immediately, apply a Web Application Firewall (WAF) rule or reverse proxy rule that:
- Rejects any request containing
%2e,%2E,..,\(backslash), or//in the URI path before it reaches the Fastify server. - Normalizes the URI using
%XXdecoding and dot-segment removal at the proxy layer (e.g., Node.jsurl.parsewithpath.normalize, or nginxmerge_slashes on;plus a location rule).
- Rejects any request containing
- Switch to the
allowedPathoption as a temporary workaround. Since applications usingallowedPathare explicitly stated to be not vulnerable, refactor the route guard to use this mechanism instead of a route-based guard. Example:fastify.register(require('@fastify/static'), { root: path.join(__dirname, 'public'), allowedPath: (pathName, root) => { return !pathName.startsWith('/private/') || isAuthenticated(request); } });
2. Patch/Upgrade Steps
- Inventory: Identify all services using
@fastify/static:npm ls @fastify/static --all - Upgrade: Update to version 10.1.3 or later:
npm update @fastify/static - Verify: After upgrade, inspect the installed version:
Confirm the version isnpm ls @fastify/static10.1.3or higher. - Test: Run a regression test that sends the traveral payloads (e.g., using a test script or
curl) against a staging environment:
Verify the requests are now rejected (403/404) or the guard is triggered.curl -v "http://staging.example.com/public/../private/test.txt" curl -v "http://staging.example.com/public/%2e%2e/private/test.txt" curl -v "http://staging.example.com/public//../private/test.txt"
3. Long-Term Hardening
- Adopt Defense-in-Depth: Even after patching, do not rely solely on the framework. Implement an application-level access control layer that:
- Decodes and normalizes the path using a single, consistent function.
- Validates against an allow-list of accessible file patterns.
- Restrict File System Permissions: Run the Fastify process with the least privilege necessary. Ensure the service account has read access only to the static root directory and not to parent or sibling directories.
- Monitor and Alert: Deploy the detection rules above and configure alerting for any anomalous path patterns.
- Stay Current: Subscribe to Fastify security advisories and the
@fastify/staticrelease notes. Since this is an incomplete-fix scenario, additional bypasses may emerge; treat any new version as mandatory even if only a minor bump. - CISA KEV Watch: CISA KEV currently shows NO for this CVE. However, given the ease of exploitation, it may be added soon — monitor the KEV catalog.
References
- NVD — CVE-2026-18427: https://nvd.nist.gov/vuln/detail/CVE-2026-18427
- @fastify/static npm package: https://www.npmjs.com/package/@fastify/static
- Fastify Security Advisories: https://github.com/fastify/fastify/security/advisories
- CWE-22 — Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal'): https://cwe.mitre.org/data/definitions/22.html
- MITRE ATT&CK T1190 — Exploit Public-Facing Application: https://attack.mitre.org/techniques/T1190/
As of the publication date, there is no evidence of active exploitation in the wild, no known threat actor campaigns leveraging this CVE, and the vulnerability is not listed on CISA's Known Exploited Vulnerabilities (KEV) catalog. However, the presence of a public PoC description (though no full exploit code) combined with the trivial nature of the exploit makes exploitation highly likely in the near term once weaponized tools are released.
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.