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", () => {
|
it("supports custom default name", () => {
|
||||||
expect(sanitizeFilename("", "invoice.pdf")).toBe("invoice.pdf");
|
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 {
|
export function sanitizeFilename(name: string, defaultName = "document.pdf"): string {
|
||||||
const sanitized = String(name || "").replace(/[\x00-\x1f"'\\\r\n]/g, "_").trim().substring(0, 200);
|
// Replace control chars, quotes, backslashes, AND forward slashes
|
||||||
return sanitized || defaultName;
|
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