{"id":"GHSA-28qf-cpwq-vmc2","kind":"vulnerability","aliases":["GHSA-28qf-cpwq-vmc2"],"related":[],"title":"Pure-Python parser request replay and buffer growth behind a declined upgrade","description":"### Summary\r\n\r\nWhen the pipelined request queue was full, the pure-Python parser stored the unparsed remainder internally and also returned it to the caller. After a handler declined an upgrade request, the buffered data was re-fed, so the buffer grew with each handled request and already-handled requests were dispatched to the application again.\r\n\r\n### Impact\r\n\r\nIf users are using the Python parser (`AIOHTTP_NO_EXTENSIONS`, or not a standard wheel installed), an attacker could cause excessive memory use and cause pipelined requests to be processed more than once.\r\n\r\n### Workaround\r\n\r\nSwitch to the default C parser.\r\n\r\n---\r\n\r\nPatch: https://github.com/aio-libs/aiohttp/commit/47babd8c23ca79e2bae6cc8dcb5752b61e369fc7","summary":"When the pipelined request queue is full, the pure-Python HTTP parser keeps the unparsed remainder and also returns it to the caller, so after a declined upgrade the data is re-fed. An attacker can make the buffer grow with each request and get already-handled requests dispatched to the application again.","severity":"medium","cvss":null,"epss":null,"exploited":false,"exploited_at":null,"products":[{"name":"aiohttp","fixed":["3.14.4"],"affected":"<= 3.14.3","ecosystem":"pypi"}],"ecosystems":["pypi"],"tags":["aiohttp","cwe-770","cwe-835","package","python","web-servers"],"not_affected_if":["c-parser","standard-wheel"],"how_to_check":"- Run `python -c \"import aiohttp; print(aiohttp.__version__)\"` and confirm it is `3.14.3` or lower.\n- Check whether the C extensions are present: `python -c \"from aiohttp import http_parser; print(http_parser.HttpRequestParser)\"` and look for a pure-Python class instead of the C one.\n- Check whether `AIOHTTP_NO_EXTENSIONS` is set in the environment or deployment config.","fix":"- `aiohttp` `3.14.4`","status":"open","published_at":"2026-11-08T18:17:48+00:00","first_seen_at":"2026-11-09T22:53:22+00:00","triaged_at":"2026-11-09T22:58:37+00:00","updated_at":"2026-11-09T22:58:37+00:00","category":"package","confidence":0.8,"triage":{"at":"2026-11-09T22:58:37Z","model":"claude-haiku-5-5","output":{"fix":"- `aiohttp` `3.14.4`","reach":"network","title":"aiohttp: pure-Python parser replays pipelined requests and grows memory","impact":"medium","summary":"When the pipelined request queue is full, the pure-Python HTTP parser keeps the unparsed remainder and also returns it to the caller, so after a declined upgrade the data is re-fed. An attacker can make the buffer grow with each request and get already-handled requests dispatched to the application again.","audience":"developers","category":"package","nicknames":[],"who_cares":["python","aiohttp","web-servers"],"confidence":0.8,"fix_status":"available","needs_auth":"no","worst_case":"Excess memory use and pipelined requests processed more than once.","analyst_note":"","how_to_check":"- Run `python -c \"import aiohttp; print(aiohttp.__version__)\"` and confirm it is `3.14.3` or lower.\n- Check whether the C extensions are present: `python -c \"from aiohttp import http_parser; print(http_parser.HttpRequestParser)\"` and look for a pure-Python class instead of the C one.\n- Check whether `AIOHTTP_NO_EXTENSIONS` is set in the environment or deployment config.","plain_action":"","product_name":"","needs_analyst":false,"not_affected_if":["c-parser","standard-wheel"],"who_is_affected":"Applications that use aiohttp with the pure-Python parser, which happens when `AIOHTTP_NO_EXTENSIONS` is set or when no standard wheel with the C extension was installed. Servers that use the default C parser are not affected according to the maintainer's workaround. Applications that handle connection upgrade requests and accept pipelined requests are the most exposed.","user_interaction":"no","product_ecosystem":"","needs_special_setup":"yes","severity_if_unknown":"medium"},"cost_usd":0.000795,"input_tokens":4777,"output_tokens":634,"severity_before":"medium"},"analyst_status":null,"analyst_note":null,"search":"'-770':27B '-835':29B '/aio-libs/aiohttp/commit/47babd8c23ca79e2bae6cc8dcb5752b61e369fc7':192C '28qf':16A,21A 'aiohttp':24A,25B,156C 'alreadi':83B,139C 'already-handl':82B,138C 'also':53B,109C 'applic':89B,146C 'attack':71B,166C 'behind':10A 'buffer':8A,75B,123C,131C 'c':187C 'caller':58B,114C 'caus':168C,173C 'could':167C 'cpwq':17A,22A 'cwe':26B,28B 'data':65B,124C 'declin':12A,62B,118C 'default':186C 'dispatch':86B,143C 'excess':169C 'extens':158C 'fed':69B,128C 'full':41B,97C 'get':81B 'ghsa':15A,20A 'ghsa-28qf-cpwq-vmc2':14A,19A 'github.com':191C 'github.com/aio-libs/aiohttp/commit/47babd8c23ca79e2bae6cc8dcb5752b61e369fc7':190C 'grew':132C 'grow':76B 'growth':9A 'handl':84B,135C,140C 'handler':117C 'http':46B 'impact':148C 'instal':164C 'intern':107C 'keep':48B 'make':73B 'memori':170C 'packag':30B 'parser':4A,47B,102C,155C,188C 'patch':189C 'pipelin':37B,93C,174C 'process':178C 'pure':2A,44B,100C 'pure-python':1A,43B,99C 'python':3A,31B,45B,101C,154C 'queue':39B,95C 're':68B,127C 're-f':67B,126C 'remaind':51B,106C 'replay':6A 'request':5A,38B,79B,85B,94C,121C,136C,141C,175C 'return':54B,110C 'server':34B 'standard':162C 'store':103C 'summari':90C 'switch':183C 'unpars':50B,105C 'upgrad':13A,63B,120C 'use':152C,171C 'user':150C 'vmc2':18A,23A 'web':33B 'web-serv':32B 'wheel':163C 'workaround':182C","nicknames":[],"mitigations":[],"who_affected":"Applications that use aiohttp with the pure-Python parser, which happens when `AIOHTTP_NO_EXTENSIONS` is set or when no standard wheel with the C extension was installed. Servers that use the default C parser are not affected according to the maintainer's workaround. Applications that handle connection upgrade requests and accept pipelined requests are the most exposed.","tier":"C","verified":{},"analyst_revisit_at":null,"fix_status":"available","audience":"developers","plain_action":null,"pkeys":["aiohttp"],"ptokens":["aiohttp"],"labels":["aiohttp","cwe770","cwe835","medium","package","pypi","python","webservers"],"campaign_type":null,"search_a":"'28qf':16A,21A 'aiohttp':24A 'behind':10A 'buffer':8A 'cpwq':17A,22A 'declin':12A 'ghsa':15A,20A 'ghsa-28qf-cpwq-vmc2':14A,19A 'growth':9A 'parser':4A 'pure':2A 'pure-python':1A 'python':3A 'replay':6A 'request':5A 'upgrad':13A 'vmc2':18A,23A","search_b":"'-770':27B '-835':29B 'aiohttp':25B 'alreadi':83B 'already-handl':82B 'also':53B 'applic':89B 'attack':71B 'buffer':75B 'caller':58B 'cwe':26B,28B 'data':65B 'declin':62B 'dispatch':86B 'fed':69B 'full':41B 'get':81B 'grow':76B 'handl':84B 'http':46B 'keep':48B 'make':73B 'packag':30B 'parser':47B 'pipelin':37B 'pure':44B 'pure-python':43B 'python':31B,45B 'queue':39B 're':68B 're-f':67B 'remaind':51B 'request':38B,79B,85B 'return':54B 'server':34B 'unpars':50B 'upgrad':63B 'web':33B 'web-serv':32B","search_c":"'/aio-libs/aiohttp/commit/47babd8c23ca79e2bae6cc8dcb5752b61e369fc7':192C 'aiohttp':156C 'alreadi':139C 'already-handl':138C 'also':109C 'applic':146C 'attack':166C 'buffer':123C,131C 'c':187C 'caller':114C 'caus':168C,173C 'could':167C 'data':124C 'declin':118C 'default':186C 'dispatch':143C 'excess':169C 'extens':158C 'fed':128C 'full':97C 'github.com':191C 'github.com/aio-libs/aiohttp/commit/47babd8c23ca79e2bae6cc8dcb5752b61e369fc7':190C 'grew':132C 'handl':135C,140C 'handler':117C 'impact':148C 'instal':164C 'intern':107C 'memori':170C 'parser':102C,155C,188C 'patch':189C 'pipelin':93C,174C 'process':178C 'pure':100C 'pure-python':99C 'python':101C,154C 'queue':95C 're':127C 're-f':126C 'remaind':106C 'request':94C,121C,136C,141C,175C 'return':110C 'standard':162C 'store':103C 'summari':90C 'switch':183C 'unpars':105C 'upgrad':120C 'use':152C,171C 'user':150C 'wheel':163C 'workaround':182C","cause_entry":null,"cause_path":null,"disclosures_checked_at":null,"first_public_at":"2026-11-08T18:17:48+00:00","kev":null,"cvss_vector":null,"cvss_by":null,"poc_count":0,"sources":[{"source":"ghsa-repo","external_id":"GHSA-28qf-cpwq-vmc2","url":"https://github.com/aio-libs/aiohttp/security/advisories/GHSA-28qf-cpwq-vmc2","severity":"medium","published_at":"2026-11-08T18:17:48+00:00","modified_at":"2026-11-08T18:34:20+00:00","first_seen_at":"2026-11-09T22:53:22+00:00","fetched_at":"2026-11-09T22:53:22+00:00","note":null}],"documents":[{"id":110555,"url":"https://github.com/aio-libs/aiohttp/security/advisories/GHSA-28qf-cpwq-vmc2","title":"Maintainer's advisory: github.com","kind":"vendor","source":"ghsa-repo","publisher":"vendor","text":null,"published_at":null,"relation":"advisory","confidence":null,"note":"Maintainer's advisory: github.com"}],"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"}