security(gateway): set explicit client_max_size on 3 uncapped aiohttp servers (#59180)

Sibling sweep from the #58902 raft review found aiohttp servers still
running on the implicit 1 MiB default with no explicit body cap:

- bluebubbles webhook (127.0.0.1): 1 MiB explicit cap — events are small
  JSON/form payloads; attachments arrive via the REST API
- teams Bot Framework listener (0.0.0.0 bind — most exposed): 1 MiB cap;
  activities are JSON well under that
- hermes proxy server: 10 MB cap mirroring api_server's MAX_REQUEST_BYTES
  (chat-completion payloads can be large, but must stay bounded)

client_max_size bounds every read path including chunked transfer-encoding
requests that carry no Content-Length (#58536/#58902 pattern).

Deliberately excluded: feishu, whatsapp_cloud, sms, line, wecom, msgraph —
open contributor PRs (#54938, #54944, #54620, #54931, #54934, #25296)
already cover those; reviewing them separately preserves their credit.

3 regression tests pin the wiring.
This commit is contained in:
Teknium 2026-07-05 14:48:28 -07:00 committed by GitHub
parent 0823230545
commit 8986981df4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 59 additions and 4 deletions

View file

@ -102,6 +102,9 @@ from gateway.platforms.base import (
logger = logging.getLogger(__name__)
_DEFAULT_PORT = 3978
# Bot Framework activities are JSON payloads well under 1 MiB; an explicit
# aiohttp client_max_size keeps oversized/chunked request bodies bounded.
_MAX_BODY_BYTES = 1_048_576
_WEBHOOK_PATH = "/api/messages"
@ -738,8 +741,12 @@ class TeamsAdapter(BasePlatformAdapter):
return False
try:
# Set up aiohttp app first — the bridge adapter wires SDK routes into it
aiohttp_app = web.Application()
# Set up aiohttp app first — the bridge adapter wires SDK routes into it.
# client_max_size: Bot Framework activities are JSON (caps out well
# under 1 MiB); an explicit cap keeps oversized/chunked bodies from
# being buffered unbounded on a 0.0.0.0 bind (same pattern as
# webhook.py / raft, #58536/#58902).
aiohttp_app = web.Application(client_max_size=_MAX_BODY_BYTES)
aiohttp_app.router.add_get("/health", lambda _: web.Response(text="ok"))
self._app = App(