CVE-2026-55558: aiosmtplib: STARTTLS response injection
Impact
When a connection is upgraded with STARTTLS, aiosmtplib reads the server's 220 go-ahead reply and immediately performs the TLS handshake without discarding any data still sitting in the receive buffer. Bytes the protocol read off the plaintext socket before the handshake survive across the plaintext→TLS boundary (the asyncio transport is swapped in place, so the protocol object and its buffer are reused), and are then parsed as though they had arrived inside the TLS session.
Who is affected: Any caller that uses STARTTLS by passing starttls=True or starttls=None when the server advertises STARTTLS, and whose traffic can be intercepted by an active network attacker on the plaintext leg of the connection.
A man in the middle can send, in a single segment immediately after the client's STARTTLS command, the 220 reply followed by attacker-chosen response lines (e.g. 220 Go ahead\r\n250-mx.evil\r\n250 AUTH LOGIN\r\n). aiosmtplib consumes only the 220, leaves the injected lines buffered, completes the handshake, and then parses the attacker's pre-staged plaintext as the first post-TLS server response. This also desynchronizes every subsequent command/response pair inside the "encrypted" session.
Not affected: Connections using implicit/direct TLS (usetls=True) have no plaintext phase and are not vulnerable. The attack requires an active man in the middle via network compromise; a passive eavesdropper cannot exploit it.
Patches
A fix is available in aiosmtplib 5.1.2. All earlier versions that support STARTTLS are affected; upgrade to 5.1.2 or later.
The fix treats any data buffered after the 220 STARTTLS reply and before the handshake as a protocol violation, per RFC 3207 §4.2 ("the client MUST discard any knowledge obtained from the server … which was not obtained from the TLS negotiation itself").
Workarounds
If you cannot upgrade immediately:
- Use implicit TLS instead of STARTTLS. Connect with usetls=True. This removes the plaintext phase entirely. - If STARTTLS is unavoidable, restrict connections to servers reached over a trusted network path.
Other sources
aiosmtplib is an asynchronous SMTP client for use with asyncio. Prior to 5.1.2, SMTPProtocol.starttls in src/aiosmtplib/protocol.py consumes the server's 220 response and starts the TLS handshake without clearing SMTPProtocol.buffer. An active network attacker can place attacker-chosen SMTP response lines after the plaintext 220 response in the same network segment. The method then calls loop.starttls; those bytes survive the transport upgrade and are parsed as the first response from inside the TLS session, desynchronizing subsequent SMTP command and response pairs. Connections using starttls=True or opportunistic STARTTLS are affected, while connections using usetls=True are not. This issue is fixed in version 5.1.2.
— MITRE
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
pip/aiosmtplibto a version that resolves this vulnerability.Fixed in 5.1.2 - Upgrade
Upgrade
aiosmtplibto a version that resolves this vulnerability.Fixed in 5.1.2 - Configuration
Use implicit/direct TLS by connecting with use_tls=True instead of start_tls=True or opportunistic STARTTLS to avoid the plaintext STARTTLS phase.
aiosmtplib (SMTP client) use_tls = True - Configuration
Avoid STARTTLS by not using start_tls=True or start_tls=None on servers that advertise STARTTLS; connections using start_tls=True or opportunistic STARTTLS are affected when traffic can be intercepted on the plaintext leg.
aiosmtplib (SMTP client) start_tls = None/True (avoid) - Compensating control
If STARTTLS is unavoidable, restrict connections to servers reached over a trusted network path to reduce the risk of an active man-in-the-middle on the plaintext leg.
Event History
Frequently Asked Questions
Which deployments are exposed to this issue?
aiosmtplib versions before 5.1.2 are affected when they use start_tls=True or opportunistic STARTTLS. Connections configured with use_tls=True are not affected.
What does an attacker need to exploit it?
An attacker must be active on the network path or same network segment and be able to inject chosen SMTP response lines immediately after the server's plaintext 220 STARTTLS response. No application privileges or user interaction are required.
What is the impact of successful exploitation?
Injected response bytes can remain buffered through the TLS transport upgrade and be treated as the first response within the TLS session. This desynchronizes later SMTP commands and responses and can compromise integrity.
What should teams do if they cannot immediately upgrade?
Use use_tls=True rather than start_tls=True or opportunistic STARTTLS where the SMTP service supports it. Upgrade to aiosmtplib 5.1.2 when possible.