Skip to content

fix(schema): max_payload_size_bytes defined but never enforced — advertised DoS control is dead code #33

Description

Audit Finding — New

What's happening

max_payload_size_bytes is defined in the AgentMessage schema at src/qwed_a2a/protocol/schema.py:130-135:

max_payload_size_bytes: Optional[int] = Field(
    default=1024 * 1024,
    description="Maximum allowed payload size in bytes. Payloads exceeding this may be blocked.",
)

This field is never enforced anywhere in the codebase. A search across all modules:

  • interceptor.py — no read of max_payload_size_bytes
  • endpoints.py — no read
  • trust_boundary.py — no read
  • crypto.py — no read

The field is parsed, stored, and silently discarded.

Why this matters

The field is advertised as a DoS control: "Payloads exceeding this may be blocked." But no code path ever checks payload size against this threshold. A consumer reading the schema reasonably assumes payload size is enforced — but it is not.

An attacker could send a payload of arbitrary size (e.g., 100MB of nested JSON) with no rejection at the interceptor level. This bypasses the documented DoS mitigation.

Current behavior

AgentMessage with 100MB payload
  → parsed by Pydantic (memory allocated)
  → interceptor.intercept() called
  → _check_trust_boundary() — no size check
  → engine routing — no size check
  → _build_verdict() — no size check
  → JWT issued, FORWARDED
  → No enforcement of max_payload_size_bytes at any point

Expected behavior

Payload size should be checked against max_payload_size_bytes early in the intercept() pipeline, before engine routing. The check should be at src/qwed_a2a/interceptor.py, ideally before _check_trust_boundary() to reject oversized payloads before any trust processing.

Files to change

  • src/qwed_a2a/interceptor.py — add payload size enforcement check in intercept()
  • Tests: add test with oversized payload → BLOCKED

Acceptance criteria

  • intercept() checks payload size against max_payload_size_bytes before engine routing
  • Payload exceeding the limit returns BLOCKED verdict with reason indicating size violation
  • Payload within the limit proceeds normally
  • If max_payload_size_bytes is None, no enforcement occurs (backward compatible)
  • Default remains 1MB

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingp2p2

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions