{"id":"GHSA-xgw8-8ccx-rmqh","kind":"vulnerability","aliases":["GHSA-xgw8-8ccx-rmqh"],"related":[],"title":"Too many URL-encoded form fields block the event loop","description":"### Summary\r\n\r\n`Request.post()` had no limit on the number of fields in a URL-encoded form body. Inserting a large number of repeated keys into a `MultiDict` took quadratic time on the event loop.\r\n\r\n### Impact\r\n\r\nAn attacker could block the event loop with a form POST within the default `client_max_size` to any handler that calls `Request.post()`.\r\n\r\n---\r\n\r\nPatch: https://github.com/aio-libs/aiohttp/commit/615fec3d4f088f30d2ee72cad760152e92aa1c53","summary":"aiohttp's Request.post() accepted any number of fields in a URL-encoded form body, and inserting many repeated keys into a MultiDict takes quadratic time. An attacker can send one form POST within the default client_max_size and block the event loop, stalling the whole server.","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","package","python","self-hosted"],"not_affected_if":["multipart-only","no-form-post-handlers"],"how_to_check":"- Check the installed version with `pip show aiohttp`\n- Look for handlers that call `Request.post()` on a URL-encoded form body\n- Check the pinned version in requirements or lock files","fix":"- aiohttp: move to `3.14.4`","status":"open","published_at":"2026-11-08T18:30:40+00:00","first_seen_at":"2026-11-09T22:53:22+00:00","triaged_at":"2026-11-09T22:58:34+00:00","updated_at":"2026-11-09T22:58:34+00:00","category":"package","confidence":0.8,"triage":{"at":"2026-11-09T22:58:34Z","model":"claude-haiku-5-5","output":{"fix":"- aiohttp: move to `3.14.4`","reach":"internet","title":"aiohttp: unlimited URL-encoded form fields let a POST stall the server","impact":"medium","summary":"aiohttp's Request.post() accepted any number of fields in a URL-encoded form body, and inserting many repeated keys into a MultiDict takes quadratic time. An attacker can send one form POST within the default client_max_size and block the event loop, stalling the whole server.","audience":"developers","category":"package","nicknames":[],"who_cares":["python","aiohttp","self-hosted"],"confidence":0.8,"fix_status":"available","needs_auth":"no","worst_case":"event loop blocked, service stalls for all users","analyst_note":"","how_to_check":"- Check the installed version with `pip show aiohttp`\n- Look for handlers that call `Request.post()` on a URL-encoded form body\n- Check the pinned version in requirements or lock files","plain_action":"","product_name":"","needs_analyst":false,"not_affected_if":["no-form-post-handlers","multipart-only"],"who_is_affected":"Any aiohttp server whose handlers call Request.post() on a URL-encoded form body is exposed, because the attacker's form POST reaches that code within the default client_max_size. Services that only serve GET requests, or that parse forms some other way, are not affected by this path.","user_interaction":"no","product_ecosystem":"","needs_special_setup":"no","severity_if_unknown":"medium"},"cost_usd":0.000719,"input_tokens":4675,"output_tokens":503,"severity_before":"medium"},"analyst_status":null,"analyst_note":null,"search":"'/aio-libs/aiohttp/commit/615fec3d4f088f30d2ee72cad760152e92aa1c53':138C '8ccx':15A,20A 'accept':32B 'aiohttp':22A,23B,29B 'attack':56B,113C 'block':8A,69B,115C 'bodi':43B,93C 'call':133C 'client':65B,126C 'could':114C 'default':64B,125C 'encod':5A,41B,91C 'event':10A,71B,109C,117C 'field':7A,36B,86C 'form':6A,42B,60B,92C,121C 'ghsa':13A,18A 'ghsa-xgw8-8ccx-rmqh':12A,17A 'github.com':137C 'github.com/aio-libs/aiohttp/commit/615fec3d4f088f30d2ee72cad760152e92aa1c53':136C 'handler':131C 'host':28B 'impact':111C 'insert':45B,94C 'key':48B,100C 'larg':96C 'limit':81C 'loop':11A,72B,110C,118C 'mani':2A,46B 'max':66B,127C 'multidict':51B,103C 'number':34B,84C,97C 'one':59B 'packag':24B 'patch':135C 'post':61B,122C 'python':25B 'quadrat':53B,105C 'repeat':47B,99C 'request.post':31B,78C,134C 'rmqh':16A,21A 'self':27B 'self-host':26B 'send':58B 'server':76B 'size':67B,128C 'stall':73B 'summari':77C 'take':52B 'time':54B,106C 'took':104C 'url':4A,40B,90C 'url-encod':3A,39B,89C 'whole':75B 'within':62B,123C 'xgw8':14A,19A","nicknames":[],"mitigations":[],"who_affected":"Any aiohttp server whose handlers call Request.post() on a URL-encoded form body is exposed, because the attacker's form POST reaches that code within the default client_max_size. Services that only serve GET requests, or that parse forms some other way, are not affected by this path.","tier":"C","verified":{},"analyst_revisit_at":null,"fix_status":"available","audience":"developers","plain_action":null,"pkeys":["aiohttp"],"ptokens":["aiohttp"],"labels":["aiohttp","medium","package","pypi","python","selfhosted"],"campaign_type":null,"search_a":"'8ccx':15A,20A 'aiohttp':22A 'block':8A 'encod':5A 'event':10A 'field':7A 'form':6A 'ghsa':13A,18A 'ghsa-xgw8-8ccx-rmqh':12A,17A 'loop':11A 'mani':2A 'rmqh':16A,21A 'url':4A 'url-encod':3A 'xgw8':14A,19A","search_b":"'accept':32B 'aiohttp':23B,29B 'attack':56B 'block':69B 'bodi':43B 'client':65B 'default':64B 'encod':41B 'event':71B 'field':36B 'form':42B,60B 'host':28B 'insert':45B 'key':48B 'loop':72B 'mani':46B 'max':66B 'multidict':51B 'number':34B 'one':59B 'packag':24B 'post':61B 'python':25B 'quadrat':53B 'repeat':47B 'request.post':31B 'self':27B 'self-host':26B 'send':58B 'server':76B 'size':67B 'stall':73B 'take':52B 'time':54B 'url':40B 'url-encod':39B 'whole':75B 'within':62B","search_c":"'/aio-libs/aiohttp/commit/615fec3d4f088f30d2ee72cad760152e92aa1c53':138C 'attack':113C 'block':115C 'bodi':93C 'call':133C 'client':126C 'could':114C 'default':125C 'encod':91C 'event':109C,117C 'field':86C 'form':92C,121C 'github.com':137C 'github.com/aio-libs/aiohttp/commit/615fec3d4f088f30d2ee72cad760152e92aa1c53':136C 'handler':131C 'impact':111C 'insert':94C 'key':100C 'larg':96C 'limit':81C 'loop':110C,118C 'max':127C 'multidict':103C 'number':84C,97C 'patch':135C 'post':122C 'quadrat':105C 'repeat':99C 'request.post':78C,134C 'size':128C 'summari':77C 'time':106C 'took':104C 'url':90C 'url-encod':89C 'within':123C","cause_entry":null,"cause_path":null,"disclosures_checked_at":null,"first_public_at":"2026-11-08T18:30:40+00:00","kev":null,"cvss_vector":null,"cvss_by":null,"poc_count":0,"sources":[{"source":"ghsa-repo","external_id":"GHSA-xgw8-8ccx-rmqh","url":"https://github.com/aio-libs/aiohttp/security/advisories/GHSA-xgw8-8ccx-rmqh","severity":"medium","published_at":"2026-11-08T18:30:40+00:00","modified_at":"2026-11-08T18:30:40+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":110558,"url":"https://github.com/aio-libs/aiohttp/security/advisories/GHSA-xgw8-8ccx-rmqh","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"}