crossbario / crossbario/autobahn-python
[META] Transport payload-size limits: consistent, correct, cross-transport enforcement
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 2.5k
- Forks
- 768
- PR merge metrics
- No merged PRs in 30d
Description
Summary
This is a tracking epic for a coordinated hardening of payload/message size
limits across the Autobahn|Python transports (WebSocket + RawSocket) and their
use in Crossbar.io. It originates from a reported denial-of-service issue
(security advisory GHSA-hxp9-w8x3-p566, "permessage-deflate bypasses
maxMessagePayloadSize after inflation", reported by Team Atlanta), but the
investigation surfaced a small cluster of related defects and design gaps that
are best fixed together so the size-limit model is finally coherent.
No development happens on this issue. Each child below is fixed on its own
issue + branch + PR, following our TDD red/green workflow (add the failing test
first, prove it red in CI, then fix, prove it green — all on the child's PR).
This epic is closed manually once all children are done.
The core problem: one knob, four possible meanings
There are two independent axes to a "size limit":
| on-the-wire (compressed) | at-the-application (uncompressed) | |
|---|---|---|
| per-frame | maxFramePayloadSize (correct) |
(no knob — covered transitively) |
| per-message | (no knob — covered transitively) | maxMessagePayloadSize |
Today maxMessagePayloadSize is documented as bounding the "re-assembled
payload" (uncompressed), enforced on send against the uncompressed message,
and enforced by RawSocket against the (uncompressed, no-compression) wire
message — but on the WebSocket receive path (Hybi/v13) it is enforced against
the compressed frame length, before inflation. A tiny compressed frame can
therefore inflate past the configured limit and reach the application. Hixie
(v0) already accounts uncompressed bytes correctly; Hybi is the outlier.
Agreed design (see child issues for detail)
- D1 — semantic anchor.
maxMessagePayloadSize= maximum size of a single
serialized WAMP message (transport payload), measured uncompressed — i.e.
before compression on send, after decompression on receive. This is already
true on send, on RawSocket, and on Hixie receive; we bring Hybi receive in
line. Default stays0(unlimited), so no existing deployment changes. - D2 — two knobs, correctly defined.
maxMessagePayloadSize(per-message,
uncompressed) +maxFramePayloadSize(per-frame, wire). The other two matrix
cells are covered transitively (enforcing the uncompressed per-message cap
during inflation also bounds a single-frame bomb; bounding uncompressed
transitively bounds accepted wire bytes). We deliberately do not add more
knobs — the existing two, defined correctly, are sufficient and less confusing. - Enforcement site. Backend-agnostic, at the inflation site in
onFrameData, so it works identically in message mode and streaming
(frame-based) mode (which differ only by whichonMessage*callbacks a
consumer overrides), and independently of the compression backend
(deflate / snappy / bzip2 / brotli).
Children (dependency-ordered)
- https://github.com/crossbario/autobahn-python/issues/1908
- https://github.com/crossbario/autobahn-python/issues/1909
- https://github.com/crossbario/autobahn-python/issues/1910
- https://github.com/crossbario/autobahn-python/issues/1911
- https://github.com/crossbario/crossbar/issues/2250
Cross-references
- Security advisory: GHSA-hxp9-w8x3-p566 (public; developed in the open).
- Related class: CVE-2016-10544 (ws / Node.js — same compressed-vs-decompressed
boundary mistake). - Ties into the Track T testing epic (parametrized both-backend / both-transport
/ multi-codec size-limit coverage; Crossbar zip-bomb functest into CI).
This work is being completed with AI assistance (Claude Code); all commits are
human-reviewed per AI_POLICY.md.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
This is a tracking epic, so start with child issues 1908, 1909, 1910, 1911, and Crossbar issue 2250 rather than making changes here. Read the agreed design and the onFrameData enforcement point; the epic is done when each child has its own tested PR and all listed work is complete.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend, networking
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 15/100