Executive brief
AsyncSSH is a Python library for building SSH clients and servers. A malicious SSH server can freeze an AsyncSSH client, and any authenticated user can freeze an AsyncSSH server, by sending a channel maximum packet size of zero. This causes the event loop to enter an uninterruptible infinite loop, making the affected process completely unavailable—either until restart or until the connection is forcibly terminated at the network level. A single authenticated account can take down an entire server.
Technical details
The vulnerability is a missing input validation flaw in AsyncSSH's channel implementation. When processing SSH_MSG_CHANNEL_OPEN_CONFIRMATION (server→client) or SSH_MSG_CHANNEL_OPEN (client→server), the code in `asyncssh/channel.py` stores the peer-supplied `send_pktsize` value without checking that it is at least 1. Later, when `SSHChannel._flush_send_buf` is called to write channel data, it enters a while loop that computes `pktsize = min(self._send_window, self._send_pktsize)`. If `_send_pktsize` is 0, then `pktsize` is 0, so `buf[:0]` extracts an empty slice, the delete operation is a no-op, and `_send_window` is never decremented. The while condition remains true indefinitely, and since the loop body contains no await statements, the entire asyncio event loop is blocked. For servers, this allows a single authenticated user to freeze all current and future connections. RFC 4254 §5.1 leaves the behavior for a peer-reported maximum packet size of 0 undefined, requiring rejection rather than storage. A fix has been proposed and verified: reject `send_pktsize == 0` with a ProtocolError in `connection.py` before storing the value.
Affected products
- Ron Frederick AsyncSSH <= 2.23.1
Timeline
- 2026-06-20: disclosed: Reported by zhangph (afldl)
- 2026-09-17: advisory: GHSA-rw4j-r22c-9gc3 published
- 2026-09-17: patched: Fix available in version 2.24.0