a2ui-project / a2ui-project/a2ui

[BUG]: Unbounded agent-supplied regex executed on the client main thread (`regex` validation function)

Open
#2,292 2 comments 0 reactions 1 assignee Claimed by @Varun-S10 View on GitHub
P2 status: first-line-handled status: needs review type: bug
Dominant language
TypeScript
Stars
16.4k
Forks
1.3k
Avg merge
2d 13h
Merged PRs (30d)
134

Description

# Unbounded agent-supplied regex executed on the client main thread (`regex` validation function)

Repository: https://github.com/a2ui-project/a2ui
Affected package: `@a2ui/web_core` (verified against published npm release 0.10.6)
CWE: CWE-1333 (Inefficient Regular Expression Complexity)

## Summary

The `regex` function of the basic catalog accepts an arbitrary pattern string supplied by the agent and executes it via `new RegExp(pattern).test(value)` during validation. Patterns with catastrophic backtracking block the renderer's main thread. Validation rules bound to a data-model path are re-evaluated on every data-model change (e.g., each keystroke in a bound TextField).

## Affected code

- `renderers/web_core/src/v0_9/basic_catalog/functions/basic_functions.ts:188-194` — `new RegExp(args.pattern).test(args.value)`
- `renderers/web_core/src/v0_9/basic_catalog/functions/basic_functions_api.ts:263-270` — `pattern: z.string()` with no length or complexity constraint
- Re-evaluation path: CHECKABLE bindings in `rendering/generic-binder.ts` → data-model change notifications

## Observed behavior (measured)

Pattern `(a+)+b` validated against user input, driven through the published package's full pipeline (`MessageProcessor.processMessages` → `ComponentContext` → `GenericBinder` → catalog invoker) with an agent-supplied `checks` array on a TextField:

| input length | blocking time |
|---|---|
| 22 chars | 48 ms |
| 24 chars | 145 ms |
| 26 chars | 600 ms |
| 32 chars (separate benchmark) | 75.7 s |
| 34 chars | did not complete within timeout |

## Impact

A remote agent can send a single spec-valid `updateComponents` message that freezes the host tab (or Electron window) whenever the user types into the bound input. This is a client-side availability issue only; no code execution or data access is involved.

## Suggested remediation

- Bound pattern length and reject unsafe patterns via static analysis (e.g. safe-regex2) or use a linear-time engine (RE2 family).
- Consider a time budget or off-main-thread evaluation for validation regexes.
- Related legacy sink: `TextField.validationRegexp` (`basic_components.ts:374`).

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.