Back to Blog
high SEVERITY4 min read

How Route Guard Bypass via Path Traversal happens in Fastify and how to fix it

A high-severity path traversal vulnerability (CVE-2026-15074) in @fastify/static version 9.0.0 allowed attackers to bypass route guards and access restricted files. The agentchatbus-ts service was upgraded from @fastify/static 9.0.0 to 10.1.2, which includes proper path normalization to prevent directory traversal attacks.

O
By Orbis AppSec
Published August 23, 2026Reviewed August 23, 2026

Answer Summary

CVE-2026-15074 is a path traversal vulnerability in @fastify/static (Node.js/Fastify) that allows attackers to bypass route guards by crafting malicious file paths with sequences like `../`. This is classified under CWE-22 (Improper Limitation of a Pathname to a Restricted Directory). The fix involves upgrading @fastify/static from version 9.0.0 to 10.1.2, which implements proper path canonicalization before serving static files.

Vulnerability at a Glance

cweCWE-22
fixUpgrade @fastify/static to version 10.1.2
riskUnauthorized access to sensitive files outside the intended directory
languageTypeScript/Node.js
root causeInsufficient path normalization in @fastify/static 9.0.0
vulnerabilityPath Traversal / Route Guard Bypass

Introduction

In the agentchatbus-ts service, a high-severity vulnerability was discovered in the static file serving layer. The package-lock.json file pinned @fastify/static to version 9.0.0, which contained CVE-2026-15074—a route guard bypass vulnerability that could allow attackers to traverse directories and access files they shouldn't reach.

This matters because agentchatbus-ts likely serves static assets to users through Fastify's static file middleware. When that middleware fails to properly normalize paths, an attacker can craft requests like GET /static/../../../etc/passwd to escape the designated static directory and read arbitrary files from the server's filesystem.

The Vulnerability Explained

What Is Path Traversal?

Path traversal (also called directory traversal) occurs when an application uses user-supplied input to construct file paths without properly validating or sanitizing that input. Attackers exploit this by inserting special sequences like ../ (dot-dot-slash) to navigate up the directory tree.

How @fastify/static 9.0.0 Was Vulnerable

In version 9.0.0, @fastify/static had insufficient path normalization logic. When a request came in for a static file, the library didn't properly canonicalize the path before checking route guards or serving the file. This meant:

// Conceptual vulnerable flow in @fastify/static 9.0.0
// Request: GET /static/../../../sensitive/config.json
// The path "../../../sensitive/config.json" wasn't properly resolved
// Route guards checking "/static/*" patterns were bypassed

The vulnerable dependency in agentchatbus-ts/package.json:

"@fastify/static": "^9.0.0"

Attack Scenario Against agentchatbus-ts

Consider this realistic attack against the agentchatbus-ts service:

  1. Reconnaissance: An attacker discovers the application serves static files at /assets/
  2. Crafting the payload: They send a request like:
    GET /assets/..%2f..%2f..%2f..%2fetc/passwd HTTP/1.1
  3. Bypassing route guards: Because the path isn't normalized before guard checks, middleware protecting routes outside /assets/ doesn't trigger
  4. File exfiltration: The server returns the contents of /etc/passwd or potentially more sensitive files like environment variables, configuration files, or source code

For an agent chat bus service handling AI/ML workloads, exposed files could include:
- API keys for model providers
- Database connection strings
- Internal service credentials
- User conversation logs

The Fix

The fix upgrades @fastify/static from version 9.0.0 to 10.1.2, which includes proper path traversal protections.

Before (Vulnerable)

// agentchatbus-ts/package.json
"@fastify/static": "^9.0.0"

// agentchatbus-ts/package-lock.json
"node_modules/@fastify/static": {
  "version": "9.0.0",
  "resolved": "https://registry.npmjs.org/@fastify/static/-/static-9.0.0.tgz",
  "dependencies": {
    "@fastify/accept-negotiator": "^2.0.0",
    "@fastify/send": "^4.0.0",
    "content-disposition": "^1.0.1",
    "fastify-plugin": "^5.0.0",
    "fastq": "^1.17.1",
    "glob": "^13.0.0"
  }
}

After (Fixed)

// agentchatbus-ts/package.json
"@fastify/static": "^10.1.2"

// agentchatbus-ts/package-lock.json
"node_modules/@fastify/static": {
  "version": "10.1.2",
  "resolved": "https://registry.npmjs.org/@fastify/static/-/static-10.1.2.tgz",
  "dependencies": {
    "@fastify/accept-negotiator": "^2.0.0",
    "@fastify/error": "^4.0.0",
    "@fastify/send": "^4.0.0",
    "content-disposition": "^2.0.1",
    "fastify-plugin": "^6.0.0",
    "fastq": "^1.17.1",
    "glob": "^13.0.0"
  }
}

Key Changes in the Upgrade

  1. New dependency added: @fastify/error (^4.0.0) — provides standardized error handling for security violations
  2. Updated content-disposition: From ^1.0.1 to ^2.0.1 — includes additional header injection protections
  3. Updated fastify-plugin: From ^5.0.0 to ^6.0.0 — better integration with Fastify's security model

The new version implements proper path canonicalization:
- Resolves symbolic links
- Normalizes ../ sequences before any security checks
- Validates the final resolved path stays within the configured root directory
- Returns 403 Forbidden for any traversal attempts

Prevention & Best Practices

1. Keep Dependencies Updated

Use automated dependency scanning in your CI/CD pipeline:

# Example GitHub Actions workflow
- name: Run Trivy vulnerability scanner
  uses: aquasecurity/trivy-action@master
  with:
    scan-type: 'fs'
    scan-ref: '.'
    severity: 'HIGH,CRITICAL'

2. Implement Defense in Depth

Even with a patched library, add application-level validation:

import path from 'path';

function isPathSafe(userPath: string, rootDir: string): boolean {
  const resolved = path.resolve(rootDir, userPath);
  return resolved.startsWith(path.resolve(rootDir));
}

3. Use Security Headers

Configure security headers to limit damage from potential exploits:

fastify.register(require('@fastify/helmet'), {
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
    },
  },
});

4. Principle of Least Privilege

Run your Node.js application with minimal filesystem permissions. Use containerization to restrict accessible paths.

Key Takeaways

  • @fastify/static 9.0.0 allowed path traversal because it didn't normalize paths before checking route guards
  • The agentchatbus-ts service was exposed to potential file exfiltration attacks through its static file serving endpoint
  • Upgrading to @fastify/static 10.1.2 adds proper path canonicalization and the @fastify/error dependency for better security error handling
  • Dependency scanning tools like Trivy can automatically detect vulnerable package versions in package-lock.json
  • Always lock and audit your transitive dependencies — the vulnerability was in a nested dependency that many developers might overlook

How Orbis AppSec Detected This

  • Source: HTTP request path parameter used for static file resolution
  • Sink: @fastify/static file serving handler in agentchatbus-ts
  • Missing control: Path normalization and boundary validation before serving files
  • CWE: CWE-22 (Improper Limitation of a Pathname to a Restricted Directory)
  • Fix: Upgraded @fastify/static from 9.0.0 to 10.1.2, which implements proper path canonicalization

Orbis AppSec automatically detected this vulnerability and opened a pull request with the fix. Try Orbis AppSec on your repositories to find and fix issues like this automatically.

Conclusion

CVE-2026-15074 in @fastify/static demonstrates why dependency management is critical for application security. A single unpatched package can expose your entire filesystem to attackers. The fix was straightforward—a version bump—but the consequences of leaving it unpatched could have been severe for the agentchatbus-ts service.

Regularly audit your dependencies, implement automated vulnerability scanning, and don't rely solely on library security—add defense in depth with application-level path validation.

References

Frequently Asked Questions

What is path traversal?

Path traversal is a vulnerability where attackers manipulate file paths using sequences like `../` to access files outside the intended directory, potentially exposing sensitive configuration files, credentials, or source code.

How do you prevent path traversal in Node.js?

Prevent path traversal by using `path.resolve()` to canonicalize paths, validating that resolved paths remain within the allowed root directory, and using well-maintained libraries like updated versions of @fastify/static that handle this automatically.

What CWE is path traversal?

Path traversal is classified as CWE-22 (Improper Limitation of a Pathname to a Restricted Directory), also known as "Path Traversal."

Is URL encoding enough to prevent path traversal?

No, URL encoding alone is insufficient because attackers can use double encoding, Unicode normalization, or other bypass techniques. Proper path canonicalization and boundary checking are required.

Can static analysis detect path traversal?

Yes, static analysis tools like Trivy, Semgrep, and Snyk can detect known vulnerable dependency versions and code patterns that may lead to path traversal vulnerabilities.

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #82

Related Articles

critical

How Path Traversal Vulnerabilities Happen in Node.js Build Scripts and How to Fix It

A critical path traversal vulnerability in `scripts/build-all.js` allowed attackers to escape the intended output directory by supplying crafted command-line arguments like `--output ../../../../etc/passwd`. The fix validates that the resolved output path remains within the repository root, preventing unauthorized file system access.

critical

How Path Traversal Vulnerabilities Happen in Node.js Development Servers and How to Fix Them

A critical path traversal vulnerability was discovered in the development file server script `serve.mjs`, where arbitrary directory paths from command-line arguments were accepted without validation. This flaw could allow attackers to serve any directory on the filesystem over HTTP, potentially exposing sensitive system files like `/etc/passwd` or application secrets. The fix adds a simple but effective validation check ensuring the serve root stays within the current working directory.

high

How Path Traversal and Security Policy Bypass Happens in Node.js Dependencies and How to Fix It

A high-severity vulnerability in the fast-uri package (CVE-2026-6321) allowed attackers to bypass security policies through improper Unicode hostname canonicalization and path traversal. This issue affected the @apralabs/apra-fleet project through its dependency tree, and was resolved by upgrading fast-uri from version 3.1.0 to 4.1.2 using npm overrides.

high

How path traversal happens in Python open() and how to fix it

A high-severity path traversal vulnerability was discovered in `src/backend/snitch.py` where the `writeTestcase()` function accepted a user-controlled `portDir` parameter without sanitization. An attacker could craft malicious input like `../../etc` to write files outside the intended output directory. The fix implements path canonicalization using `pathlib.Path.resolve()` and validates that the final destination stays within the allowed base directory.

high

How URL-Encoded Path Traversal happens in Python nltk.data.load() and how to fix it

CVE-2026-54293 is a high-severity path traversal vulnerability in NLTK's `nltk.data.load()` function that allows attackers to read arbitrary local files by supplying URL-encoded path sequences. The fix pins NLTK to version 3.10.0 or later via a constraint dependency in `pyproject.toml`, preventing the vulnerable version from being resolved transitively through `rouge-score` and `lm-eval`. Because this project is a web service, the vulnerability was directly exploitable by remote attackers withou

high

How Information Disclosure and DoS via malformed Cache-Control directives happens in Node.js undici and how to fix it

A high-severity vulnerability (CVE-2026-13697) in the undici HTTP client library allowed attackers to trigger information disclosure and denial of service through malformed Cache-Control directives. The @jackwener/opencli project upgraded undici from version 7.24.6 to 7.29.0, eliminating the vulnerability in their dependency chain and protecting downstream consumers from exploitation.