/** * Defensive NoSQL / operator-injection sanitizer. Walks the value tree * and either drops or rejects keys that look like operators or nested * paths. Idempotent, allocates a new object rather than mutating input. * * Also unconditionally strips the prototype-pollution vectors `__proto__`, * `constructor`, and `prototype`, and writes output keys as own properties * (never via the prototype chain) so a `__proto__` key in the input can't * shift the returned object's prototype. * * @param {unknown} input * @param {SanitizeBodyOptions} [options] * @returns {unknown} */ export function sanitizeBody(input: unknown, options?: SanitizeBodyOptions): unknown; /** * @typedef {object} SanitizeParamsOptions * @property {'first' | 'last' | 'array'} [mode='first'] * How to collapse duplicate query keys. * - `first` — take the earliest value (safest default; matches most * server-side language runtimes). * - `last` — take the trailing value. * - `array` — leave arrays as-is; caller handles ambiguity. * @property {number} [maxParams=1000] * Reject payloads with more distinct keys than this — a soft DoS guard. */ /** * HTTP Parameter Pollution (HPP) sanitizer. Different runtimes disagree on * how to interpret `?x=1&x=2`; attackers exploit the divergence between * parser and business logic. This normalizes to a single value per key. * * @param {Record} query Parsed query object. * @param {SanitizeParamsOptions} [options] * @returns {Record} */ export function sanitizeParams(query: Record, options?: SanitizeParamsOptions): Record; /** * Resolve a user-provided path segment(s) within a fixed base directory. * Guards against `..` traversal, absolute-path smuggling, and null-byte * tricks. Returns the fully-resolved absolute path when safe, or throws * SecurityError when the joined path escapes the base. * * @param {string} base Absolute base directory (trusted). * @param {...string} segments User-controlled path pieces. * @returns {string} Absolute, canonicalized path. */ export function safeJoin(base: string, ...segments: string[]): string; /** * Normalize a user-supplied filename into something safe to write to disk * on Windows, macOS, and Linux. Strips path separators, control chars, * reserved Windows names, and leading/trailing dots. * * @param {unknown} input * @param {SanitizeFilenameOptions} [options] * @returns {string} */ export function sanitizeFilename(input: unknown, options?: SanitizeFilenameOptions): string; export type SanitizeParamsOptions = { /** * How to collapse duplicate query keys. * - `first` — take the earliest value (safest default; matches most * server-side language runtimes). * - `last` — take the trailing value. * - `array` — leave arrays as-is; caller handles ambiguity. */ mode?: "first" | "last" | "array" | undefined; /** * Reject payloads with more distinct keys than this — a soft DoS guard. */ maxParams?: number | undefined; }; export type SanitizeBodyOptions = { /** * `strip` silently removes suspicious keys; `reject` throws * SecurityError. Use `reject` on trusted APIs where a bad shape * indicates a bug (or attack) worth alerting on. */ mode?: "strip" | "reject" | undefined; /** * Test applied to each own-property key. Default catches MongoDB * operators (`$gt`, `$where`, …) and dotted keys (`a.b.c`) that * Mongoose interprets as nested paths. */ suspicious?: RegExp | undefined; /** * Recursion guard against pathological / self-referential payloads. * * Regardless of `suspicious`, the prototype-pollution keys `__proto__`, * `constructor`, and `prototype` are ALWAYS treated as dangerous — they * cannot be re-enabled by narrowing the regex. */ maxDepth?: number | undefined; }; export type SanitizeFilenameOptions = { /** * Replacement for illegal characters. */ replacement?: string | undefined; /** * Cap the returned length. */ maxLength?: number | undefined; /** * Returned when everything got stripped. */ fallback?: string | undefined; };