Path traversal: reading files outside the intended folder
When a request supplies part of a file path, ../ walks up out of the folder you meant and into the rest of the file system.
Example
app.get("/files", (req, res) => {
res.sendFile(path.join(__dirname, "uploads", req.query.name));
});const BASE = path.resolve(__dirname, "uploads");
app.get("/files", (req, res) => {
const target = path.resolve(BASE, String(req.query.name));
if (!target.startsWith(BASE + path.sep)) return res.sendStatus(400);
res.sendFile(target);
});How it happens
Download endpoints, image resizers and template loaders join a base folder with a name from the request. path.join does not stop ../../../../etc/passwd; neither does checking that the string starts with the folder name before it is resolved. Writes are worse than reads: overwriting a startup script or a template turns traversal into code execution.
How to fix it
Resolve first, then check.
- Map an identifier to a stored path on the server instead of accepting paths
- Otherwise resolve the full path and confirm it is still inside the base directory
- Use path.basename when only a file name is expected
- Run the process with the least file-system access it needs
How RepoVerse finds it
- HighRequest input becomes a filesystem path
`../` sequences walk out of the intended directory and read or overwrite any file the process can reach.
data flow · CWE-22
- ModerateRequest value joined into a filesystem path
A path is built from something that arrived with the request.
pattern
Questions
- Does URL-decoding matter for path traversal?
- Yes. Encoded forms such as %2e%2e%2f decode to ../ before the file system sees them, so checks must run on the decoded, resolved path.
- How does RepoVerse find path traversal?
- It traces request input into fs calls and res.sendFile, res.download and similar sinks, and treats basename() and literal-led paths as safe.
Related
- SSRF: when a request decides where your server connectsHow SSRF (CWE-918) lets a request choose where your server connects — internal services, cloud metadata at 169.254.169.254 — and how to build URLs safely.
- Command injection: when a parameter runs a shell commandHow OS command injection (CWE-78) turns a request parameter into a second shell command, the safe execFile pattern, and how to find exec calls fed by user input.
- GitHub security scanner for code, secrets and dependenciesScan a GitHub repository for injection flaws, leaked secrets and vulnerable dependencies. Data-flow traces from request to sink, lockfile-aware, with fixes.
Updated 2026-10-11