Good Code
The good version validates the filename, resolves it against a known root, and rejects paths that escape the upload directory.
Lesson 10
Validate user input before using it in filesystem paths or other sensitive operations.
import path from "node:path";
const uploadRoot = path.resolve("uploads");
export function resolveUploadPath(fileName: string) {
if (!/^[a-z0-9._-]+$/i.test(fileName)) {
throw new Error("Invalid file name.");
}
const targetPath = path.resolve(uploadRoot, fileName);
if (!targetPath.startsWith(uploadRoot + path.sep)) {
throw new Error("Path escapes upload directory.");
}
return targetPath;
}import path from "node:path";
export function resolveUploadPath(fileName: string) {
return path.join("uploads", fileName);
}The good version validates the filename, resolves it against a known root, and rejects paths that escape the upload directory.
The bad version joins user input directly into a filesystem path, allowing traversal input to point outside the intended folder.