Skip to content
eastbaycyber

CVE-2026-15074: @fastify/static Route Guard Bypass

CVE explainers 8 min read
SR
Security Research Desk Expert reviewed
Threat intelligence · Human-verified · Updated 2026-07-23
▲ Escalation ViewOne CVE, briefed at three altitudes — skim the Brief, weigh the Impact, or work the Runbook. The way a SOC actually reads it.
CISOBrief · 30-second brief

TL;DR - @fastify/static through 10.1.0 can bypass route-scoped guards due to .. path handling. - Affects apps relying on middleware or URL prefixes to protect files inside the static root. - Upgrade to 10.1.1 promptly; no confirmed in-the-wild exploitation is currently known.

1) Vulnerability at a Glance

Field Value
CVE ID CVE-2026-15074
CVSS 7.5
Attack vector Network
Privileges required None
Patch available Yes, upgrade to @fastify/static 10.1.1

This CVE affects the Fastify ecosystem’s static file serving plugin, @fastify/static. According to the NVD description, versions “up to and including 10.1.0” fail to reject dot-dot path segments in request paths before file resolution. That creates a route guard bypass condition rather than a full filesystem breakout.

For defenders, the key operational point is scope. The bug does not by itself let an attacker escape outside the configured static root. However, it does let an unauthenticated requester potentially bypass route-scoped middleware and fetch files that remain inside the static root but were assumed to be protected by URL prefixing or application routing logic.

2) What Is This Vulnerability?

At its core, CVE-2026-15074 is an input validation and path normalization flaw in @fastify/static. The plugin did not reject .. path segments early enough in the request lifecycle. The earlier remediation for CVE-2026-6414 addressed encoded forward slashes, but this newer issue shows that additional path normalization paths still allowed guarded routes to be bypassed.

The NVD description is especially important here because it clarifies the mechanics: the underlying send library normalizes dot segments before applying its own path traversal guard. That sequencing matters. If route-level logic makes authorization decisions on the original request path, but downstream file resolution normalizes it into another effective path, an attacker can reach files that application logic intended to shield.

This makes the issue less like classic “../../../etc/passwd” traversal and more like an authorization bypass inside a trusted file tree. In practice, that means defenders should focus on what lives inside the configured static root. If sensitive downloads, build outputs, customer-specific exports, internal documentation, or pre-release assets are stored there and protected only by middleware or route prefixes, they may be exposed.

Technical Notes

A simplified example of the risky architectural pattern looks like this:

const fastify = require('fastify')()
const path = require('path')

fastify.register(require('@fastify/static'), {
  root: path.join(__dirname, 'public'),
  prefix: '/assets/'
})

// Example of route-scoped protection assumption
fastify.addHook('preHandler', async (req, reply) => {
  if (req.url.startsWith('/assets/private/')) {
    return reply.code(403).send({ error: 'forbidden' })
  }
})

If authorization assumptions depend on the request path before normalization, but the file-serving layer resolves a normalized path later, the guard and the actual file fetch can diverge.

AnalystImpact · assess the risk

3) Who Is Affected?

The affected product is @fastify/static, the Fastify static file serving plugin maintained in the Fastify project and covered by the OpenJS Foundation CNA advisory. The affected version range is explicitly documented as “up to and including 10.1.0”. The fixed version is 10.1.1.

That means any deployment using @fastify/static 10.1.0 or earlier should be reviewed. If you are uncertain whether your application includes the package directly or through a service template, inspect package.json, package-lock.json, npm ls, pnpm list, or yarn why. Managed Node.js applications often carry plugin dependencies forward for long periods, especially in internal services that do not update framework components frequently.

The most exposed environments are those where static content under a single root includes both public and restricted material, with access control enforced through Fastify routes, hooks, middleware, or URL prefix assumptions. If your team stores only truly public assets in the static root and keeps sensitive content elsewhere, your exposure may be lower. If not, treat this as a potentially significant information disclosure issue.

Technical Notes

Useful inventory commands:

npm ls @fastify/static
pnpm list @fastify/static
yarn why @fastify/static

A direct dependency entry may look like this:

{
  "dependencies": {
    "@fastify/static": "10.1.0"
  }
}

4) CVSS Score Breakdown

NVD lists this issue with a CVSS base score of 7.5, which places it in the High severity range. The full vector was not provided in the research note, so defenders should avoid over-asserting individual metric values beyond what the source confirms. Still, the narrative supports several likely characteristics: network-reachable, no authentication required, and confidentiality impact due to unauthorized file reads inside the static root.

A 7.5 score is consistent with internet-exposed application weaknesses that permit unauthorized access without prior privileges. Even though this is not a full host compromise or arbitrary code execution bug, it can still have serious business impact. Exposed internal files may contain secrets, deployment metadata, private customer content, or staging artifacts that enable follow-on attacks.

Because the official vector details are not available in the supplied source set, defenders should assume worst reasonable case for exposed web services: if the application is internet-accessible and the static root contains anything non-public, remediation should be prioritized as a near-term patch.

5) Exploitation Status

At the time of writing, there is no CISA KEV listing for CVE-2026-15074. That means there is no CISA-confirmed evidence of active exploitation in the wild based on KEV status. It is important to phrase this carefully: absence from KEV is not proof that nobody is exploiting it. It only means there is no KEV-backed confirmation in the provided data.

The research context also indicates that no public proof of concept was identified in the reviewed primary references. The GitHub Security Advisory and OpenJS Foundation CNA advisory confirm the issue exists, but the source material provided does not identify a public exploit repository, exploit write-up, or active attack campaign.

For blue teams, that places this CVE in the “patch before it becomes routine scan traffic” category. The affected logic is simple enough that independent rediscovery is plausible. Even without a published PoC, path normalization and authorization mismatch bugs are commonly easy for attackers to test once advisories become public.

Technical Notes

Current known status based on the provided sources:

  • Public PoC: None identified from provided references
  • Confirmed in-the-wild exploitation: Not confirmed
  • CISA KEV listed: No

Defender assumption in absence of better telemetry: public disclosure of a remotely reachable unauthenticated bug can quickly lead to opportunistic probing, especially for popular JavaScript web stacks.

ResponderRunbook · act now

6) How to Detect It

Detection should focus on suspicious request paths sent to Fastify static routes, especially any path containing .. segments, normalized traversal attempts, or unexpected requests aimed at protected subpaths under the static root. Since the issue concerns route-scoped middleware bypass rather than escaping the root entirely, defenders should pay attention to successful 200 responses for assets under paths that should normally require authorization or should never be fetched directly.

Review HTTP access logs, reverse proxy logs, CDN logs, and application logs for requests that include ../, %2e%2e, or adjacent path normalization artifacts. Also compare requests reaching supposedly protected prefixes against authentication logs. A request to a guarded file path with no corresponding auth event is a high-value hunting lead.

Technical Notes

Example grep patterns for common logs:

grep -RniE '(\.\.|%2e%2e|%2E%2E)' /var/log/nginx /var/log/apache2 /var/log/app 2>/dev/null

Example NGINX-style log pattern to hunt:

"GET /assets/../private/report.pdf HTTP/1.1" 200
"GET /static/%2e%2e/secure/build-info.json HTTP/1.1" 200

Example Splunk query:

index=web_logs ("../" OR "%2e%2e" OR "%2E%2E")
| stats count values(uri_path) values(status) by src_ip user_agent host

Example Sigma-like logic concept for SIEM translation:

title: Suspicious Dot-Dot Requests to Static Routes
logsource:
  category: webserver
detection:
  selection:
    cs-uri-query|contains:
      - ".."
    cs-uri-stem|contains:
      - ".."
  condition: selection
level: medium

If your Fastify app logs request URLs, search for requests containing dot-dot segments that resulted in 200 or 304 responses from static file endpoints. That combination is more useful than looking only for blocked attempts.

7) Mitigation and Patching

The primary fix is to upgrade @fastify/static to 10.1.1 or later. The vulnerable range is explicitly stated as up to and including 10.1.0, and the NVD description states that 10.1.1 contains the patch. If your dependency tree pins an earlier version, update directly and regenerate the lockfile.

Patching alone should not end the response. Teams should also review the contents of the configured static root and remove any files that are not intended for broad unauthenticated distribution. This vulnerability demonstrates why static roots should contain only public assets whenever possible. Sensitive downloads, private customer exports, and internal build artifacts belong outside public-serving directories and behind explicit authorization checks.

Where immediate upgrade is not possible, a practical workaround is to reject any request containing .. path segments at the reverse proxy or edge before it reaches the application. This is a mitigation, not a substitute for patching, because application-level edge cases and path normalization nuances can be tricky.

Technical Notes

Upgrade commands:

npm install @fastify/static@10.1.1
pnpm add @fastify/static@10.1.1
yarn add @fastify/static@10.1.1

Verify installed version:

npm ls @fastify/static

Example NGINX mitigation to block obvious dot-dot path segments:

location / {
    if ($request_uri ~* "\.\.") {
        return 400;
    }
    proxy_pass http://app_backend;
}

Example application-side defensive check if an emergency temporary guard is needed:

fastify.addHook('onRequest', async (req, reply) => {
  if (req.raw.url && req.raw.url.includes('..')) {
    return reply.code(400).send({ error: 'invalid path' })
  }
})

After patching, retest access controls around any static content under previously guarded prefixes and confirm sensitive files are no longer reachable through path normalization tricks.

8) References

The authoritative references for this CVE come from the OpenJS Foundation CNA listing, the GitHub Security Advisory for the Fastify project, and NVD. Those sources establish the affected package, the vulnerable version range, the general root cause, and the fixed version. They also support the current statement that there is no KEV-backed confirmation of active exploitation.

For more information on related topics, check out our articles on spear phishing and how to spot social engineering attacks.

This article may contain affiliate links. We earn a commission on qualifying purchases at no extra cost to you.

Last verified: 2026-07-23

Disclaimer: This article may contain affiliate links. We earn a commission on qualifying purchases at no extra cost to you.