← All fixes

Fix it

Path traversal from user input — how to fix it

High severityCWE-22 (Path Traversal)

When a filename or path from a request is joined onto a directory, an attacker can send ../ sequences to escape that directory and read or write files elsewhere on the server. The fix is to resolve the final path and confirm it still sits inside the directory you intended before you touch it.

Why it's a problem

A path like ../../../../etc/passwd or an absolute path can pull files far outside your intended folder, exposing configuration, other users' uploads, or credentials. The same flaw on a write or delete operation lets an attacker overwrite files they should never reach.

The pattern

// user controls the filename
const file = path.join(uploadDir, req.query.name);
res.sendFile(file);

The fix

const requested = path.resolve(uploadDir, req.query.name);
// confirm the resolved path is still inside uploadDir
if (!requested.startsWith(path.resolve(uploadDir) + path.sep)) {
  return res.sendStatus(400);
}
res.sendFile(requested);

Why AI tools write this

Joining a directory and a request parameter is the obvious way to express 'serve the file the user asked for,' and it works perfectly for normal filenames. The traversal only shows up when someone deliberately sends ../ sequences, which a happy-path test never does.

The quick fix

  • Resolve the final path and confirm it starts inside your intended directory.
  • Strip path separators or use path.basename when you only expect a bare filename.
  • Prefer an allowlist of known files or ids over accepting arbitrary paths.

Want to know if this pattern is already in a repo you shipped? Scan a public repo free, no account needed.

Scan a repo →
Path Traversal (../) From User Input — How to Fix It: Prbl