Skip to content

fix: escape input.id before regex construction to prevent ReDoS#9370

Open
karan68 wants to merge 1 commit intomicrosoft:mainfrom
karan68:fix/redos-input-id-regex-escape
Open

fix: escape input.id before regex construction to prevent ReDoS#9370
karan68 wants to merge 1 commit intomicrosoft:mainfrom
karan68:fix/redos-input-id-regex-escape

Conversation

@karan68
Copy link
Copy Markdown

@karan68 karan68 commented May 8, 2026

Summary
Escape regex metacharacters in input.id before injecting it into a RegExp constructor in StringWithSubstitutions.getReferencedInputs() (shared.ts line 87).

Problem
input.id from untrusted card JSON is concatenated directly into new RegExp() without escaping. A crafted id like (a+)+ causes catastrophic backtracking when the regex is executed against URL templates containing near-match patterns.

Affected code path: HttpAction.internalGetReferencedInputs() -> StringWithSubstitutions.getReferencedInputs()

Standard actions (Action.Submit, Action.Execute, Action.OpenUrl) use different code paths and are NOT affected.

Fix
Added escapeRegExp() inline to sanitize input.id before regex construction. This escapes all regex metacharacters: . * + ? ^ $ { } ( ) | [ ] \

Verification

  • Normal input IDs (e.g. userName) still match {{userName.value}} correctly
  • Malicious IDs (e.g. (a+)+) neutralized: 0ms vs 13,350ms with 28 chars
  • All 28 existing jest tests pass
  • TypeScript compilation clean
  • Webpack build succeeds

Reproduction
Parse a card with "id": "(a+)+" on an Input element and "type": "Action.Http" with URL {{aaa...28 chars...XXXXX}}, then click the action button. Browser freezes for 13+ seconds without this fix.

…ions.getReferencedInputs

Escape regex metacharacters in input.id before injecting it into a RegExp
constructor in shared.ts. Without escaping, a crafted input.id like '(a+)+'
causes catastrophic backtracking (ReDoS) when matched against URL templates
containing near-match patterns.

Affected code path: Action.Http -> StringWithSubstitutions.getReferencedInputs()
Standard actions (Submit, Execute, OpenUrl) are NOT affected as they use
different code paths that don't call this method.

Verified:
- Normal input IDs still match correctly (e.g. 'userName' matches {{userName.value}})
- Malicious IDs neutralized (0ms vs 13,350ms with 28 chars)
- All 28 existing jest tests pass
- TypeScript compilation and webpack build succeed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants