{"id":"CVE-2026-115559","kind":"vulnerability","aliases":["CVE-2026-115559"],"related":[],"title":"Python imaplib: STARTTLS accepts plaintext bytes sent before the TLS handshake","description":"IMAP4.starttls() wraps the socket in TLS but leaves self._readbuf, imaplib's own read-ahead buffer, untouched. Any plaintext bytes that arrived in the same recv() as the tagged OK to STARTTLS are returned by readline() after the handshake, so the client treats them as the first responses on the protected channel. A network attacker who cannot break TLS can append forged lines after the server's OK, let the handshake complete with the real server and a valid certificate, and have the client accept the forged CAPABILITY and the forged tagged completion of the next command. This is the STARTTLS command/response injection class of CVE-2011-0411.","summary":"Python's imaplib keeps a read-ahead buffer that is not cleared when STARTTLS upgrades the connection, so plaintext lines the server sent before the handshake are treated as trusted TLS responses. A network attacker who can sit on the connection can inject forged IMAP responses, such as a fake CAPABILITY list or a fake completion for the next command, while the TLS certificate still validates.","severity":"medium","cvss":6.3,"epss":null,"exploited":false,"exploited_at":null,"products":[],"ecosystems":[],"tags":["email-clients","imaplib","python","runtime"],"not_affected_if":["implicit-tls","no-starttls","trusted-network"],"how_to_check":"- Run `python3 --version` and compare against the fixed versions below.\n- Search your code for `starttls(` used on `imaplib.IMAP4` clients, since that is the affected path.","fix":"- Python: unknown (the sources do not state a fixed version)","status":"open","published_at":"2026-11-10T19:19:11+00:00","first_seen_at":"2026-11-10T19:24:44+00:00","triaged_at":"2026-11-10T19:58:27+00:00","updated_at":"2026-11-10T19:58:27+00:00","category":"runtime","confidence":0.6,"triage":{"at":"2026-11-10T19:58:27Z","model":"claude-haiku-5-5","output":{"fix":"- Python: unknown (the sources do not state a fixed version)","reach":"network","title":"Python imaplib: STARTTLS accepts plaintext bytes sent before the TLS handshake","impact":"medium","summary":"Python's imaplib keeps a read-ahead buffer that is not cleared when STARTTLS upgrades the connection, so plaintext lines the server sent before the handshake are treated as trusted TLS responses. A network attacker who can sit on the connection can inject forged IMAP responses, such as a fake CAPABILITY list or a fake completion for the next command, while the TLS certificate still validates.","audience":"developers","category":"runtime","nicknames":[],"who_cares":["python","imaplib","email-clients"],"confidence":0.6,"fix_status":"unknown","needs_auth":"no","worst_case":"forged mail server responses are accepted as genuine over TLS","analyst_note":"Confirm the fixed Python versions from the Python security-announce post and the NVD entry; the sources here do not name them.","how_to_check":"- Run `python3 --version` and compare against the fixed versions below.\n- Search your code for `starttls(` used on `imaplib.IMAP4` clients, since that is the affected path.","plain_action":"","product_name":"","needs_analyst":true,"not_affected_if":["implicit-tls","no-starttls","trusted-network"],"who_is_affected":"Applications that call IMAP4.starttls() in Python's standard imaplib to fetch mail over an untrusted network. Clients that use implicit TLS (IMAP4_SSL) or do not use STARTTLS are not in the described path. Exploitation requires a network attacker positioned on the connection before the handshake completes.","user_interaction":"no","product_ecosystem":"runtime","needs_special_setup":"yes","severity_if_unknown":"medium"},"cost_usd":0.000793,"input_tokens":4743,"output_tokens":638,"severity_before":"medium"},"analyst_status":null,"analyst_note":null,"search":"'-0411':198C '-115559':14A,17A '-2011':197C '-2026':13A,16A 'accept':4A,175C 'ahead':31B,105C 'append':151C 'arriv':112C 'attack':59B,145C 'break':148C 'buffer':32B,106C 'byte':6A,110C 'cannot':147C 'capabl':75B,178C 'certif':88B,170C 'channel':142C 'class':194C 'clear':36B 'client':20B,132C,174C 'command':84B,187C 'command/response':192C 'complet':80B,162C,183C 'connect':41B,65B 'cve':12A,15A,196C 'email':19B 'email-cli':18B 'fake':74B,79B 'first':137C 'forg':68B,152C,177C,181C 'handshak':11A,50B,129C,161C 'imap':69B 'imap4.starttls':91C 'imaplib':2A,21B,26B,100C 'inject':67B,193C 'keep':27B 'leav':98C 'let':159C 'line':44B,153C 'list':76B 'network':58B,144C 'next':83B,186C 'ok':120C,158C 'plaintext':5A,43B,109C 'protect':141C 'python':1A,22B,24B 'read':30B,104C 'read-ahead':29B,103C 'readlin':126C 'real':165C 'recv':116C 'respons':56B,70B,138C 'return':124C 'runtim':23B 'self._readbuf':99C 'sent':7A,47B 'server':46B,156C,166C 'sit':62B 'socket':94C 'starttl':3A,38B,122C,191C 'still':89B 'tag':119C,182C 'tls':10A,55B,87B,96C,149C 'treat':52B,133C 'trust':54B 'untouch':107C 'upgrad':39B 'valid':90B,169C 'wrap':92C","nicknames":[],"mitigations":[],"who_affected":"Applications that call IMAP4.starttls() in Python's standard imaplib to fetch mail over an untrusted network. Clients that use implicit TLS (IMAP4_SSL) or do not use STARTTLS are not in the described path. Exploitation requires a network attacker positioned on the connection before the handshake completes.","tier":"C","verified":{},"analyst_revisit_at":null,"fix_status":"unknown","audience":"developers","plain_action":null,"pkeys":[],"ptokens":[],"labels":["emailclients","imaplib","medium","python","runtime"],"campaign_type":null,"search_a":"'-115559':14A,17A '-2026':13A,16A 'accept':4A 'byte':6A 'cve':12A,15A 'handshak':11A 'imaplib':2A 'plaintext':5A 'python':1A 'sent':7A 'starttl':3A 'tls':10A","search_b":"'ahead':31B 'attack':59B 'buffer':32B 'capabl':75B 'certif':88B 'clear':36B 'client':20B 'command':84B 'complet':80B 'connect':41B,65B 'email':19B 'email-cli':18B 'fake':74B,79B 'forg':68B 'handshak':50B 'imap':69B 'imaplib':21B,26B 'inject':67B 'keep':27B 'line':44B 'list':76B 'network':58B 'next':83B 'plaintext':43B 'python':22B,24B 'read':30B 'read-ahead':29B 'respons':56B,70B 'runtim':23B 'sent':47B 'server':46B 'sit':62B 'starttl':38B 'still':89B 'tls':55B,87B 'treat':52B 'trust':54B 'upgrad':39B 'valid':90B","search_c":"'-0411':198C '-2011':197C 'accept':175C 'ahead':105C 'append':151C 'arriv':112C 'attack':145C 'break':148C 'buffer':106C 'byte':110C 'cannot':147C 'capabl':178C 'certif':170C 'channel':142C 'class':194C 'client':132C,174C 'command':187C 'command/response':192C 'complet':162C,183C 'cve':196C 'first':137C 'forg':152C,177C,181C 'handshak':129C,161C 'imap4.starttls':91C 'imaplib':100C 'inject':193C 'leav':98C 'let':159C 'line':153C 'network':144C 'next':186C 'ok':120C,158C 'plaintext':109C 'protect':141C 'read':104C 'read-ahead':103C 'readlin':126C 'real':165C 'recv':116C 'respons':138C 'return':124C 'self._readbuf':99C 'server':156C,166C 'socket':94C 'starttl':122C,191C 'tag':119C,182C 'tls':96C,149C 'treat':133C 'untouch':107C 'valid':169C 'wrap':92C","cause_entry":null,"cause_path":null,"disclosures_checked_at":null,"first_public_at":"2026-11-10T17:41:54+00:00","kev":null,"cvss_vector":"CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X","cvss_by":"cna@python.org","poc_count":0,"sources":[{"source":"nvd","external_id":"CVE-2026-115559","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-115559","severity":null,"published_at":"2026-11-10T19:19:11+00:00","modified_at":"2026-11-10T19:19:11+00:00","first_seen_at":"2026-11-10T19:24:44+00:00","fetched_at":"2026-11-10T19:24:44+00:00","note":null}],"documents":[{"id":116800,"url":"https://mail.python.org/archives/list/security-announce@python.org/message/LVAGFOFG26QVXEM6VXXPRMMOZBHM4CVB/","title":"Python security-announce: [Security-announce][CVE-2026-115559] imaplib STARTTLS serves plaintext bytes buffered before the handshake as if they came over TLS","kind":"advisory","source":"advisory","publisher":null,"text":"[Security-announce][CVE-2026-115559] imaplib STARTTLS serves plaintext bytes buffered before the handshake as if they came over TLS\n\nThere is a medium severity vulnerability affecting the imaplib library in CPython. IMAP4.starttls() wraps the socket in TLS but leaves self._readbuf, imaplib's own read-ahead buffer, untouched. Any plaintext bytes that arrived in the same recv() as the tagged OK to STARTTLS are returned by readline() after the handshake, so the client treats them as the first responses on the protected channel. A network attacker who cannot break TLS can append forged lines after the server's OK, let the handshake complete with the real server and a valid certificate, and have the client accept the forged CAPABILITY and the forged tagged completion of the next command. This is the STARTTLS command/response injection class of CVE-2011-0411. First affected release: 3.14.0. The regression comes from the IMAP4 IDLE support in gh-55454 (commit 0fef47e), which replaced self._file.readline() with the custom _readbuf buffering. Before that, starttls() replaced the file object and so discarded buffered plaintext; 3.13.13 is not affected. Please see the linked CVE ID for the latest information on affected versions: * https://www.cve.org/CVERecord?id=CVE-2026-115559 * https://github.com/python/cpython/pull/160370 Thanks to ＠digit50 for reporting this issue.","published_at":"2026-11-10T17:41:54+00:00","relation":"advisory","confidence":null,"note":null}],"disclosures":[],"exploit_sources":[],"notice":"Free to read, with fair use of about 60 pages a minute. For higher limits or API access: sales@infrastack.ai"}