fix(security): harden regex compilation for filters and redaction

This commit is contained in:
Peter Steinberger
2026-02-23 23:54:46 +00:00
parent e6484cb65f
commit a2dfe9879f
8 changed files with 238 additions and 16 deletions

View File

@@ -93,6 +93,15 @@ describe("redactSensitiveText", () => {
expect(output).toBe("token=abcdef…ghij");
});
it("ignores unsafe nested-repetition custom patterns", () => {
const input = `${"a".repeat(28)}!`;
const output = redactSensitiveText(input, {
mode: "tools",
patterns: ["(a+)+$"],
});
expect(output).toBe(input);
});
it("skips redaction when mode is off", () => {
const input = "OPENAI_API_KEY=sk-1234567890abcdef";
const output = redactSensitiveText(input, {

View File

@@ -1,4 +1,5 @@
import type { OpenClawConfig } from "../config/config.js";
import { compileSafeRegex } from "../security/safe-regex.js";
import { resolveNodeRequireFromMeta } from "./node-require.js";
const requireConfig = resolveNodeRequireFromMeta(import.meta.url);
@@ -51,15 +52,11 @@ function parsePattern(raw: string): RegExp | null {
return null;
}
const match = raw.match(/^\/(.+)\/([gimsuy]*)$/);
try {
if (match) {
const flags = match[2].includes("g") ? match[2] : `${match[2]}g`;
return new RegExp(match[1], flags);
}
return new RegExp(raw, "gi");
} catch {
return null;
if (match) {
const flags = match[2].includes("g") ? match[2] : `${match[2]}g`;
return compileSafeRegex(match[1], flags);
}
return compileSafeRegex(raw, "gi");
}
function resolvePatterns(value?: string[]): RegExp[] {