fix: sanitize path traversal in filename (TDD)
Some checks failed
Build & Deploy to Staging / Build & Deploy to Staging (push) Failing after 2m0s
Some checks failed
Build & Deploy to Staging / Build & Deploy to Staging (push) Failing after 2m0s
This commit is contained in:
parent
f0cb83a901
commit
9e1d4d86fb
2 changed files with 46 additions and 2 deletions
|
|
@ -21,4 +21,35 @@ describe("sanitizeFilename", () => {
|
|||
it("supports custom default name", () => {
|
||||
expect(sanitizeFilename("", "invoice.pdf")).toBe("invoice.pdf");
|
||||
});
|
||||
|
||||
// Path traversal security tests
|
||||
it("removes path traversal attempts with ../", () => {
|
||||
const result = sanitizeFilename("../../etc/passwd");
|
||||
expect(result).not.toContain("/");
|
||||
expect(result).not.toContain("..");
|
||||
});
|
||||
|
||||
it("removes path traversal with single ../", () => {
|
||||
const result = sanitizeFilename("../secret.pdf");
|
||||
expect(result).not.toContain("/");
|
||||
expect(result).not.toContain("..");
|
||||
});
|
||||
|
||||
it("replaces forward slashes in folder/file paths", () => {
|
||||
const result = sanitizeFilename("folder/file.pdf");
|
||||
expect(result).not.toContain("/");
|
||||
expect(result).toContain("_");
|
||||
});
|
||||
|
||||
it("handles whitespace-only filename", () => {
|
||||
expect(sanitizeFilename(" ")).toBe("document.pdf");
|
||||
});
|
||||
|
||||
it("handles filename with only special characters", () => {
|
||||
expect(sanitizeFilename("///...")).toBe("document.pdf");
|
||||
});
|
||||
|
||||
it("still handles null bytes correctly", () => {
|
||||
expect(sanitizeFilename("file\x00.pdf")).toBe("file_.pdf");
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,4 +1,17 @@
|
|||
export function sanitizeFilename(name: string, defaultName = "document.pdf"): string {
|
||||
const sanitized = String(name || "").replace(/[\x00-\x1f"'\\\r\n]/g, "_").trim().substring(0, 200);
|
||||
return sanitized || defaultName;
|
||||
// Replace control chars, quotes, backslashes, AND forward slashes
|
||||
let sanitized = String(name || "")
|
||||
.replace(/[\x00-\x1f"'\\\r\n/]/g, "_")
|
||||
.trim()
|
||||
.substring(0, 200);
|
||||
|
||||
// Replace any sequence of dots (including ".." path traversal)
|
||||
sanitized = sanitized.replace(/\.{2,}/g, "_");
|
||||
|
||||
// Strip leading dots to prevent hidden files or remaining single dots
|
||||
sanitized = sanitized.replace(/^\.+/, "");
|
||||
|
||||
// If result is empty or only underscores/dots/whitespace, return default
|
||||
const cleaned = sanitized.replace(/[_.\s]/g, "");
|
||||
return cleaned ? sanitized.trim() : defaultName;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue