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:
- Reconnaissance: An attacker discovers the application serves static files at
/assets/ - Crafting the payload: They send a request like:
GET /assets/..%2f..%2f..%2f..%2fetc/passwd HTTP/1.1 - Bypassing route guards: Because the path isn't normalized before guard checks, middleware protecting routes outside
/assets/doesn't trigger - File exfiltration: The server returns the contents of
/etc/passwdor 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
- New dependency added:
@fastify/error(^4.0.0) — provides standardized error handling for security violations - Updated
content-disposition: From ^1.0.1 to ^2.0.1 — includes additional header injection protections - 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/errordependency 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/staticfile 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.