[BUG]: Validation Bypass via Mixed Client/Server Messages in A2uiValidator

Open Beginner friendly
#2,579 2 comments 0 reactions 1 assignee View on GitHub

@Varun-S10 is already working on this.

Since Sep 10, 2026.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
75/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
python

Research direction

The bug is in agent_sdks/python/a2ui_core/src/a2ui/core/validating/validator.py at line 248. Start by reading the validate method and the is_client_payload logic. The fix is to change the any(...) condition to all(...) or to raise an error for mixed payloads. Run the existing tests for the validator to ensure the change doesn't break existing client payload validation, and add a test for the mixed-payload bypass case to confirm the fix.

Written by the indexing model from the issue text.

Description

P2 status: first-line-handled type: bug

Location

agent_sdks/python/a2ui_core/src/a2ui/core/validating/validator.py:248

Description

The A2uiValidator.validate method contains a logic flaw in its is_client_payload detection. It iterates over a list of messages and checks if any() message contains client-specific keys (action, error, or data). If this evaluates to True, the method immediately returns, skipping all protocol envelope, catalog schema, and topology integrity validation. An attacker controlling the A2UI JSON stream (e.g., a prompt-injected agent) can craft a payload containing both a dummy client message and malicious server messages (e.g., un-whitelisted components, recursive structures, or exploit payloads). The presence of the client message satisfies the any() condition, completely bypassing the SDK's validation checks and passing the unvalidated malicious payload to downstream processing.

Impact

Bypass of the primary validation layer (TB-1). Malicious agents can deliver malformed or exploit-bearing A2UI JSON payloads that would otherwise be rejected, enabling downstream attacks such as Prototype Pollution or Resource Exhaustion depending on the renderer's sink behaviors.

Mitigation

Modify the is_client_payload check to ensure all messages belong to the client namespace, e.g., using all(...) instead of any(...). Alternatively, enforce that payloads cannot mix client and server messages, raising an error if a mixed payload is detected.

Reproduction Steps

Create an A2UI payload with multiple messages.
In the first message, include a client key: {"action": {"functionCall": {"name": "dummy"}}}.
In the second message, include an invalid or malicious server message, e.g., a createSurface message with invalid component schemas or recursive definitions.
Call A2uiValidator.validate() on this payload array.
Observe that the validator silently accepts the payload without raising an A2uiValidatorError.

Evidence

        is_client_payload = any(
            isinstance(m, dict) and any(k in m for k in (\"action\", \"error\", \"data\"))
            for m in messages
        )
        if is_client_payload:
            return

Reasoning

The A2uiValidator.validate method takes an a2ui_payload and processes it into a list of messages. It then contains a check: is_client_payload = any(isinstance(m, dict) and any(k in m for k in ("action", "error", "data")) for m in messages). If is_client_payload evaluates to True, the function immediately returns without validating any of the messages. An attacker can construct a payload consisting of a list of messages where at least one message contains an "action", "error", or "data" key, and the subsequent messages can be arbitrary unvalidated payloads. Because of the early return, the rest of the payload completely bypasses schema, topological, and protocol validation. This clearly allows maliciously crafted server messages to bypass validation if mixed with a dummy client message.

Dominant language
TypeScript
Stars
16.4k
Forks
1.3k
Avg merge
3d 5h
Merged PRs (30d)
117

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from a2ui-project/a2ui

All issues in a2ui-project/a2ui

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.