Path Traversal in Restify
How Path Traversal Manifests in Restify
Path traversal (CWE-22) exploits insufficient validation of user-supplied file paths, allowing attackers to access files outside intended directories. In Restify, this vulnerability commonly arises when route parameters are used to construct file system paths without sanitization. Restify's router extracts URL parameters into req.params as raw strings, with no automatic normalization or validation. If these parameters are passed directly to file operations like fs.readFile or used with path.join, an attacker can insert ../ sequences to escape the intended directory.
Consider a typical Restify endpoint for serving user-uploaded documents:
const path = require('path');
const fs = require('fs');
server.get('/docs/:filename', (req, res, next) => {
const filePath = path.join(__dirname, 'uploads', req.params.filename);
fs.readFile(filePath, (err, data) => {
if (err) {
res.send(404, 'Not found');
return next();
}
res.setHeader('Content-Type', 'application/pdf');
res.send(data);
return next();
});
});Here, req.params.filename is trusted implicitly. An attacker requesting /docs/../../../etc/passwd could read the system password file on Unix-like systems. This violates OWASP API Top 10's Broken Object Level Authorization (BOLA) because the attacker accesses a file object without proper authorization checks.
Restify's minimalistic design does not include built-in path traversal protection. Even when using restify.plugins.directory for static files, misconfiguration—such as mounting the plugin on a route with user-controlled subpaths—can introduce vulnerabilities. Additionally, Restify automatically decodes percent-encoded characters (e.g., %2e%2e%2f becomes ../), bypassing naive filters that look for literal ../ strings.
The impact ranges from sensitive data exposure (configuration files, source code) to potential remote code execution if combined with write capabilities. Real-world incidents include CVE-2021-21315 in a Restify-based application where path traversal led to credential theft.
Restify-Specific Detection
Detecting path traversal in Restify APIs requires testing endpoints that accept file-related parameters (e.g., filename, path, doc). Manual testing involves sending payloads like ../../../etc/passwd (Unix) or ..\..\..\windows\win.ini (Windows) and observing responses for file content, error messages, or status code changes. However, automated scanning is more efficient and thorough.
middleBrick automates this detection by sending a curated set of traversal payloads to vulnerable parameter locations (path, query, body) derived from the OpenAPI spec or heuristic analysis. It analyzes responses for:
- Exact matches of known file signatures (e.g.,
root:x:0:0from/etc/passwd). - Error messages revealing file system paths (e.g.,
ENOENT: no such file or directory, open '/var/www/../../../etc/passwd'). - Unexpected 200 OK responses where 404/403 were expected.
middleBrick's scan takes 5–15 seconds and maps findings to the BOLA/IDOR and Input Validation categories. The scanner includes payloads tailored to Restify's behavior, such as double-encoded sequences (%252e%252e%252f) that Restify will decode twice. Example payloads include:
| Payload | Target OS | Purpose |
|---|---|---|
| ../../../etc/passwd | Unix/Linux | Read system password file |
| ..\..\..\windows\win.ini | Windows | Read Windows configuration |
| ....//....//....//etc/passwd | Any | Bypass slash-based filters |
| ../../../etc/passwd%00 | Legacy | Null byte truncation |
| /.%0a/etc/passwd | Any | Newline injection |
If your Restify API has an OpenAPI spec, middleBrick resolves $ref pointers to identify file-related parameters and prioritizes them during scanning. The result is a letter grade (A–F) with per-category scores, prioritized findings, and remediation steps—all without requiring credentials or agents.
Restify-Specific Remediation
Fixing path traversal in Restify requires validating and canonicalizing all user-supplied path components before file system access. Never trust req.params, req.query, or body parameters that influence file paths.
1. Use path.normalize and path.resolve with a base directory check. Resolve the user-supplied path against a known safe directory and verify the result starts with that directory's absolute path:
const path = require('path');
const fs = require('fs');
const BASE_DIR = path.resolve(__dirname, 'uploads');
server.get('/docs/:filename', (req, res, next) => {
// Normalize to remove '..' and '.' segments
const normalized = path.normalize(req.params.filename);
// Resolve to absolute path within BASE_DIR
const resolvedPath = path.resolve(BASE_DIR, normalized);
// Ensure the resolved path is still within BASE_DIR
if (!resolvedPath.startsWith(BASE_DIR + path.sep)) {
res.send(403, 'Forbidden');
return next();
}
fs.readFile(resolvedPath, (err, data) => {
// ... serve file or handle error
});
});2. For static files, use restify.plugins.directory with a fixed root. This plugin already prevents traversal above its configured directory:
server.get('/static/*', restify.plugins.directory({
directory: path.join(__dirname, 'public'),
index: false
}));Avoid dynamic directory parameters (e.g., /static/:dir/*) unless you validate :dir against a whitelist.
3. Implement filename whitelisting where possible. If the set of accessible files is known, use an allowlist:
const ALLOWED_FILES = new Set(['report.pdf', 'image.png']);
server.get('/docs/:filename', (req, res, next) => {
if (!ALLOWED_FILES.has(req.params.filename)) {
res.send(403, 'Forbidden');
return next();
}
// Safe to use
});4. Apply defense in depth. Ensure the Node.js process runs with minimal filesystem permissions (e.g., read-only access to uploads/). Also, combine path validation with authentication/authorization checks—especially for sensitive files.
After remediation, rescan with middleBrick's CLI (middlebrick scan <url>) or GitHub Action to confirm the vulnerability is resolved. middleBrick's scoring will reflect improved Input Validation and BOLA/IDOR scores, helping you maintain a secure Restify API.
Related CWEs: inputValidation
| CWE ID | Name | Severity |
|---|---|---|
| CWE-20 | Improper Input Validation | HIGH |
| CWE-22 | Path Traversal | HIGH |
| CWE-74 | Injection | CRITICAL |
| CWE-77 | Command Injection | CRITICAL |
| CWE-78 | OS Command Injection | CRITICAL |
| CWE-79 | Cross-site Scripting (XSS) | HIGH |
| CWE-89 | SQL Injection | CRITICAL |
| CWE-90 | LDAP Injection | HIGH |
| CWE-91 | XML Injection | HIGH |
| CWE-94 | Code Injection | CRITICAL |
Frequently Asked Questions
How does middleBrick detect path traversal in Restify APIs?
../../../etc/passwd) to the target endpoint, targeting parameters identified from the OpenAPI spec or through heuristic analysis. It analyzes responses for file content, error messages, or status code anomalies that indicate successful traversal. The scan runs in 5–15 seconds and reports findings under the BOLA/IDOR and Input Validation categories with severity ratings and remediation guidance.