refactor(security): split safe-regex parse and bounded matching

This commit is contained in:
Peter Steinberger
2026-03-02 16:46:31 +00:00
parent 8611fd67b5
commit 031bf0c6c0
4 changed files with 210 additions and 169 deletions

View File

@@ -24,7 +24,7 @@ import type {
import { logDebug, logError } from "../../logger.js";
import { normalizeAccountId, resolveAgentIdFromSessionKey } from "../../routing/session-key.js";
import type { RuntimeEnv } from "../../runtime.js";
import { compileSafeRegex } from "../../security/safe-regex.js";
import { compileSafeRegex, testRegexWithBoundedInput } from "../../security/safe-regex.js";
import {
GATEWAY_CLIENT_MODES,
GATEWAY_CLIENT_NAMES,
@@ -34,8 +34,6 @@ import { createDiscordClient, stripUndefinedFields } from "../send.shared.js";
import { DiscordUiContainer } from "../ui.js";
const EXEC_APPROVAL_KEY = "execapproval";
const SESSION_FILTER_REGEX_MAX_INPUT = 2048;
export type { ExecApprovalRequest, ExecApprovalResolved };
/** Extract Discord channel ID from a session key like "agent:main:discord:channel:123456789" */
@@ -368,28 +366,12 @@ export class DiscordExecApprovalHandler {
if (!session) {
return false;
}
const head = session.slice(0, SESSION_FILTER_REGEX_MAX_INPUT);
const tail =
session.length > SESSION_FILTER_REGEX_MAX_INPUT
? session.slice(-SESSION_FILTER_REGEX_MAX_INPUT)
: "";
const matches = config.sessionFilter.some((p) => {
if (session.includes(p)) {
return true;
}
const regex = compileSafeRegex(p);
if (!regex) {
return false;
}
regex.lastIndex = 0;
if (regex.test(head)) {
return true;
}
if (tail) {
regex.lastIndex = 0;
return regex.test(tail);
}
return false;
return regex ? testRegexWithBoundedInput(regex, session) : false;
});
if (!matches) {
return false;