You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* start new dev branch; add audit file
* Add failing tests: asyncio RawSocket receive limit must be configurable (#1911)
The asyncio RawSocket receive size limit is hardwired to 16 MB: the dead
max_size=None branch in RawSocketProtocol.__init__ always yields length exponent
15, and there is no asyncio equivalent of the Twisted factory's
setProtocolOptions(maxMessagePayloadSize=...). So an asyncio WAMP peer cannot
tighten its receive cap for DoS hardening, and Crossbar's rawsocket
max_message_size has no effect on the asyncio path - a both-backend parity gap.
- test_aio_rawsocket.py: parametrized tests (RECV_LIMIT_CASES) asserting that
after setProtocolOptions(maxMessagePayloadSize=N) the server handshake
advertises the configured length exponent and enforces the matching receive
cap (N rounded up to the next power of two), plus a test that a frame declaring
more octets than the configured cap (but under 16 MB) is rejected.
- test_tx_rawsocket.py: the same table asserted against the Twisted backend
(already configurable) as the parity contract - the two backends cannot be
imported into one process (autobahn.twisted forces txaio.use_twisted), so
parity is pinned by both matching the same formula.
To make the asyncio red behavioural rather than an AttributeError,
setProtocolOptions/resetProtocolOptions are added to the asyncio factory but not
yet applied to the protocol (__call__ ignores the configured value), so the new
tests fail because the cap stays hardwired at 16 MB. Enforcement lands next.
Note: This work was completed with AI assistance (Claude Code).
* Make the asyncio RawSocket receive limit configurable (#1911)
Activate the configuration surface added in the previous commit so
setProtocolOptions(maxMessagePayloadSize=...) actually reaches the protocol,
reaching parity with the Twisted backend.
- WampRawSocketFactory.__call__ now pushes the factory's _max_message_size onto
the protocol via _set_max_message_size().
- RawSocketProtocol grows _set_max_message_size(max_size), which rounds the
configured max up to the next power of two and derives the advertised
handshake length exponent (2 ** (9 + exp)) and enforced receive cap, the same
formula the Twisted backend uses. The dead max_size=None branch in __init__ is
removed; __init__ keeps the 16 MB default for a protocol built without a
factory.
An asyncio WAMP peer can now tighten its RawSocket receive cap for DoS
hardening, and Crossbar's RawSocket max_message_size takes effect on the asyncio
path. Makes the tests added in the previous commit pass; the Twisted parity test
pins both backends to the same accept/reject decisions.
Note: This work was completed with AI assistance (Claude Code).
-[ ] I did **not** use any AI-assistance tools to help create this pull request.
2
+
-[x] I **did** use AI-assistance tools to *help* create this pull request.
3
+
-[x] I have read, understood and followed the projects' [AI Policy](https://github.com/crossbario/autobahn-python/blob/main/AI_POLICY.md) when creating code, documentation etc. for this pull request.
Copy file name to clipboardExpand all lines: docs/changelog.rst
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -13,6 +13,7 @@ Changelog
13
13
* Fix WebSocket ``maxMessagePayloadSize`` being enforced against the compressed on-the-wire frame length instead of the uncompressed reassembled message size when permessage-compress (deflate/bzip2/snappy/brotli) is negotiated. A small compressed frame could inflate far beyond the configured limit and be delivered to the application (a decompression-bomb style denial-of-service; security advisory GHSA-hxp9-w8x3-p566, same class as CVE-2016-10544). The limit is now re-checked at the inflation site against the running uncompressed message size, and the connection is failed with close code 1009 (message too big) before delivery — for both the whole-message and streaming receive APIs and every compression backend. Behaviour change: a compressed message that inflates past ``maxMessagePayloadSize`` is now rejected where it previously passed; uncompressed traffic and the per-frame ``maxFramePayloadSize`` wire guard are unaffected (#1909)
14
14
* Fix the permessage-deflate ``max_message_size`` receive cap silently truncating an over-limit message and raising a zlib error instead of cleanly rejecting it: the bounded ``decompress(…, max_length)`` left the remaining input in ``unconsumed_tail`` undrained, so the message was corrupted rather than reported. Decompression is now bounded cumulatively across frames and raises ``PayloadExceededError`` as soon as the uncompressed size would exceed the cap (#1908)
15
15
* Make bounded decompression backend-agnostic: ``decompress_message_data()`` gains an optional ``max_output_len`` argument (documented on the ``PerMessageCompress`` base class) and every permessage-compress backend now honours it. deflate and bzip2 stop inflating once the limit is reached (native incremental cap); snappy and brotli, whose libraries expose no output-length argument, inflate the frame (already bounded on the wire by ``maxFramePayloadSize``) and then reject — a weaker but still clean per-frame guarantee. The WebSocket receive path passes the remaining ``maxMessagePayloadSize`` budget so a compressed frame no longer expands unbounded into memory before the size check; the previous post-inflation check (#1909) remains as a backstop. Previously only deflate had any decompressed-output cap, so a snappy/bzip2/brotli frame could inflate fully into memory first (#1910)
16
+
* Make the asyncio RawSocket receive size limit configurable, at parity with the Twisted backend. The asyncio ``WampRawSocketFactory`` now exposes ``setProtocolOptions(maxMessagePayloadSize=...)`` / ``resetProtocolOptions()`` (bounds ``[512, 2**24]``, default 16 MB), and the configured value drives both the advertised handshake length exponent and the enforced receive cap (rounded up to the next power of two), matching the Twisted factory. Previously the asyncio receive limit was hardwired to 16 MB (a dead ``max_size=None`` branch), so an asyncio WAMP peer could not tighten its RawSocket receive limit for DoS hardening and Crossbar's RawSocket ``max_message_size`` had no effect on the asyncio path (#1911)
0 commit comments