small security fixes

This commit is contained in:
KingKDot
2026-06-08 13:53:58 -05:00
parent 9fcb607902
commit 9a1fc96e2b
12 changed files with 395 additions and 55 deletions
@@ -0,0 +1,37 @@
import path from "path";
const WINDOWS_RESERVED_NAMES = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])$/i;
export function sanitizeUploadFilename(
name: string | undefined | null,
fallback = "upload.bin",
maxLength = 128,
): string {
const fallbackName = fallback || "upload.bin";
const raw = String(name || "").replace(/\\/g, "/").split("/").pop() || fallbackName;
const cleaned = raw
.trim()
.replace(/[^\w.\-() ]/g, "_")
.replace(/\s+/g, " ")
.slice(0, maxLength);
if (!cleaned || cleaned === "." || cleaned === ".." || /^[. ]+$/.test(cleaned)) {
return fallbackName;
}
const stem = cleaned.replace(/\.+$/, "").split(".")[0] || cleaned;
if (WINDOWS_RESERVED_NAMES.test(stem)) {
return `_${cleaned}`;
}
return cleaned;
}
export function resolveContainedPath(root: string, ...segments: string[]): string {
const resolvedRoot = path.resolve(root);
const resolvedPath = path.resolve(resolvedRoot, ...segments);
if (resolvedPath !== resolvedRoot && !resolvedPath.startsWith(`${resolvedRoot}${path.sep}`)) {
throw new Error("Resolved path escapes target root");
}
return resolvedPath;
}