Skip to content

A2A: REJECT mode accepts arbitrary bodyless GET paths #46378

Description

@yanavlasov

Originally reported by @ekilmer

A2A extension is in alpha state and can be fixed in the open


A2A: REJECT mode accepts arbitrary bodyless GET paths

Brief description

The alpha envoy.filters.http.a2a filter treats every bodyless downstream GET request as valid A2A discovery traffic. When configured with traffic_mode: REJECT, non-discovery paths such as /internal/admin can be forwarded instead of receiving the local 400 response intended for non-A2A traffic.

The A2A filter is alpha-tagged.

CVSS

CVSS v3.1: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N

Score: 3.7

Rating: LOW

Scoped severity from the report: Low.

Impact

A downstream client can send a bodyless GET request to an arbitrary path and have it accepted as A2A traffic by the filter in REJECT mode. Practical impact depends on an A2A-only gateway sharing the same listener, route, or virtual host with sensitive non-A2A GET endpoints.

No crash is involved.

You are impacted if

You may be impacted if all of the following are true:

  • You configure alpha envoy.filters.http.a2a.
  • The A2A filter uses traffic_mode: REJECT.
  • The same listener, route, or virtual host can reach non-A2A GET endpoints that should be rejected by the A2A filter.
  • Downstream clients can send requests to those endpoints.

Affected component(s)

  • Alpha component: envoy.filters.http.a2a
  • source/extensions/filters/http/a2a/a2a_filter.cc
  • api/envoy/extensions/filters/http/a2a/v3/a2a.proto

Attack vector(s)

A remote downstream client sends a bodyless GET request to a non-discovery path on an Envoy deployment with the A2A filter in REJECT mode.

GET /internal/admin HTTP/1.1
Host: gateway.example

Discover(s)/Credits

Eric Kilmer and Benjamin Samuels of Trail of Bits in collaboration with OpenAI.

Example exploit or proof-of-concept

Configuration condition:

name: envoy.filters.http.a2a
typed_config:
  "@type": type.googleapis.com/envoy.extensions.filters.http.a2a.v3.A2a
  traffic_mode: REJECT

Details

source/extensions/filters/http/a2a/a2a_filter.cc:34-35 returns true for every GET. decodeHeaders() then marks a bodyless GET as A2A and returns Continue at source/extensions/filters/http/a2a/a2a_filter.cc:68-71, before the REJECT mode non-A2A check at source/extensions/filters/http/a2a/a2a_filter.cc:91-96.

This conflicts with the API documentation in api/envoy/extensions/filters/http/a2a/v3/a2a.proto, which describes REJECT mode as rejecting requests that are not following A2A.

Mitigations / Workarounds

Potential mitigations include isolating A2A routes from sensitive non-A2A GET endpoints, avoiding REJECT mode as the only guard on shared routes, or applying the patch when available in the relevant branch or release.

Detection

Review configurations for envoy.filters.http.a2a with traffic_mode: REJECT, especially where A2A traffic shares a listener, route, or virtual host with sensitive GET endpoints.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions