fix: harden auth, SSRF, query engine, and cookie security
This commit is contained in:
@@ -231,6 +231,7 @@ function evalOp(op: string, fieldVal: unknown, opVal: unknown): boolean {
|
||||
case "$regex": {
|
||||
if (typeof fieldVal !== "string" || typeof opVal !== "string") return false;
|
||||
if (opVal.length > 200) return false;
|
||||
if (isSafeRegex(opVal) === false) return false;
|
||||
try {
|
||||
return new RegExp(opVal).test(fieldVal);
|
||||
} catch {
|
||||
@@ -250,6 +251,18 @@ function toNum(v: unknown): number {
|
||||
return typeof v === "number" ? v : Number(v) || 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reject regex patterns likely to cause catastrophic backtracking (ReDoS).
|
||||
* Blocks nested quantifiers like (a+)+ and star-height > 1 patterns.
|
||||
*/
|
||||
function isSafeRegex(pattern: string): boolean {
|
||||
// Reject nested quantifiers: (x+)+, (x*)+, (x+)*, (x{n,})+, etc.
|
||||
if (/\([^)]*[+*}]\)[+*{]/.test(pattern)) return false;
|
||||
// Reject overlapping alternation with quantifiers: (a|a)+
|
||||
if (/\([^)]*\|[^)]*\)[+*{]/.test(pattern)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// ── Validate ───────────────────────────────────────────────────────────
|
||||
|
||||
const VALID_OPS = new Set([
|
||||
|
||||
Reference in New Issue
Block a user