flawopen.com/Path Traversal/Node path.join()

Is Node's path.join() enough to prevent path traversal?

Reference page — draft, pending review
Short answer

No — a common misconception. path.join() normalizes path segments, but it doesn't stop .. from walking outside an intended directory. You need to verify the resolved path is still inside the intended base directory afterward.

STILL VULNERABLE
const filePath = path.join(
  BASE_DIR, userFilename
);
// userFilename = "../../etc/passwd"
// still escapes BASE_DIR
FIXED
const filePath = path.join(
  BASE_DIR, userFilename
);
const resolved = path.resolve(filePath);
if (!resolved.startsWith(
  path.resolve(BASE_DIR) + path.sep
)) {
  throw new Error("Invalid path");
}

Why join() alone doesn't help

path.join()'s job is to correctly combine path segments with the right separators and clean up redundant slashes — it explicitly does not remove or reject .. segments, because .. is a legitimate part of many valid paths. A filename of ../../etc/passwd joined with a base directory still resolves outside that base directory; join() was never designed to prevent that.

FAQ

Does path.normalize() help instead?

It resolves .. segments within the string, but still doesn't verify the result stays inside a specific base directory — the explicit "does the resolved path start with the base directory" check is still needed.

References