From 6073770c6b623a8763e3143f4e06dfec6f6ed0e4 Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Mon, 13 Apr 2026 19:59:30 -0700 Subject: [PATCH 1/4] fix(security): resolve ReDoS vulnerability in function execute tag pattern Simplified regex to eliminate overlapping quantifiers that caused exponential backtracking on malformed input without closing delimiter. --- apps/sim/app/api/function/execute/route.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/sim/app/api/function/execute/route.ts b/apps/sim/app/api/function/execute/route.ts index 2328bf11fbb..f3cf5178404 100644 --- a/apps/sim/app/api/function/execute/route.ts +++ b/apps/sim/app/api/function/execute/route.ts @@ -494,7 +494,7 @@ function resolveTagVariables( const undefinedLiteral = language === 'python' ? 'None' : 'undefined' const tagPattern = new RegExp( - `${REFERENCE.START}([a-zA-Z_](?:[a-zA-Z0-9_${REFERENCE.PATH_DELIMITER}]*[a-zA-Z0-9_])?)${REFERENCE.END}`, + `${REFERENCE.START}([a-zA-Z_][a-zA-Z0-9_${REFERENCE.PATH_DELIMITER}]*)${REFERENCE.END}`, 'g' ) const tagMatches = resolvedCode.match(tagPattern) || [] From 28f3401cac757e4c4230541392bfaef6b48a37ee Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Mon, 13 Apr 2026 20:05:44 -0700 Subject: [PATCH 2/4] fix(security): exclude trailing-dot refs and hoist tag pattern to module level --- apps/sim/app/api/function/execute/route.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/apps/sim/app/api/function/execute/route.ts b/apps/sim/app/api/function/execute/route.ts index f3cf5178404..0923d2ea5d8 100644 --- a/apps/sim/app/api/function/execute/route.ts +++ b/apps/sim/app/api/function/execute/route.ts @@ -27,6 +27,11 @@ export const MAX_DURATION = 210 const logger = createLogger('FunctionExecuteAPI') +const TAG_PATTERN = new RegExp( + `${REFERENCE.START}([a-zA-Z_](?:\\${REFERENCE.PATH_DELIMITER}[a-zA-Z0-9_]+|[a-zA-Z0-9_])*)${REFERENCE.END}`, + 'g' +) + const E2B_JS_WRAPPER_LINES = 3 const E2B_PYTHON_WRAPPER_LINES = 1 @@ -493,11 +498,7 @@ function resolveTagVariables( let resolvedCode = code const undefinedLiteral = language === 'python' ? 'None' : 'undefined' - const tagPattern = new RegExp( - `${REFERENCE.START}([a-zA-Z_][a-zA-Z0-9_${REFERENCE.PATH_DELIMITER}]*)${REFERENCE.END}`, - 'g' - ) - const tagMatches = resolvedCode.match(tagPattern) || [] + const tagMatches = resolvedCode.match(TAG_PATTERN) || [] for (const match of tagMatches) { const tagName = match.slice(REFERENCE.START.length, -REFERENCE.END.length).trim() From dc4125116a4d86bda603f5a9d7fb5afbb572694a Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Mon, 13 Apr 2026 20:08:17 -0700 Subject: [PATCH 3/4] fix(security): align tag pattern with codebase standard [^<>]+ pattern Matches createReferencePattern() from reference-validation.ts used by the core executor. Invalid refs handled gracefully by resolveBlockReference. --- apps/sim/app/api/function/execute/route.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/sim/app/api/function/execute/route.ts b/apps/sim/app/api/function/execute/route.ts index 0923d2ea5d8..761c6e70364 100644 --- a/apps/sim/app/api/function/execute/route.ts +++ b/apps/sim/app/api/function/execute/route.ts @@ -28,7 +28,7 @@ export const MAX_DURATION = 210 const logger = createLogger('FunctionExecuteAPI') const TAG_PATTERN = new RegExp( - `${REFERENCE.START}([a-zA-Z_](?:\\${REFERENCE.PATH_DELIMITER}[a-zA-Z0-9_]+|[a-zA-Z0-9_])*)${REFERENCE.END}`, + `${REFERENCE.START}([^${REFERENCE.START}${REFERENCE.END}]+)${REFERENCE.END}`, 'g' ) From 4e21a08fd473406e9f2148739bcef6e211c8d39f Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Mon, 13 Apr 2026 20:21:08 -0700 Subject: [PATCH 4/4] refactor(security): use createReferencePattern() instead of inline regex --- apps/sim/app/api/function/execute/route.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/apps/sim/app/api/function/execute/route.ts b/apps/sim/app/api/function/execute/route.ts index 761c6e70364..e172f31d771 100644 --- a/apps/sim/app/api/function/execute/route.ts +++ b/apps/sim/app/api/function/execute/route.ts @@ -18,6 +18,7 @@ import { type OutputSchema, resolveBlockReference } from '@/executor/utils/block import { formatLiteralForCode } from '@/executor/utils/code-formatting' import { createEnvVarPattern, + createReferencePattern, createWorkflowVariablePattern, } from '@/executor/utils/reference-validation' export const dynamic = 'force-dynamic' @@ -27,10 +28,7 @@ export const MAX_DURATION = 210 const logger = createLogger('FunctionExecuteAPI') -const TAG_PATTERN = new RegExp( - `${REFERENCE.START}([^${REFERENCE.START}${REFERENCE.END}]+)${REFERENCE.END}`, - 'g' -) +const TAG_PATTERN = createReferencePattern() const E2B_JS_WRAPPER_LINES = 3 const E2B_PYTHON_WRAPPER_LINES = 1