{"id":"GHSA-24c4-3p7v-29cm","kind":"vulnerability","aliases":["GHSA-24c4-3p7v-29cm"],"related":[],"title":"Base64 multipart parts bypass client_max_size","description":"### Summary\r\n\r\nWhen reading a multipart part with `Content-Transfer-Encoding: base64`, `BodyPartReader.read_chunk()` kept reading until the chunk length was a multiple of 4, with no byte limit. A part with a short `Content-Length`, or a long run of whitespace, could cause the entire remaining body to be read into memory within a single call before any size check, or spin on the event loop.\r\n\r\n### Impact\r\n\r\nAn attacker could bypass `client_max_size` to cause excessive memory use, or block the event loop, with a specially crafted multipart request to any handler that reads multipart data.\r\n\r\n---\r\n\r\nPatch: https://github.com/aio-libs/aiohttp/commit/a555ab698e08e9baea7386d5b4c0761cb8956fdd","summary":"aiohttp's multipart reader keeps reading base64-encoded parts without a byte limit until the chunk length is a multiple of four. A crafted multipart request can make the server load the whole remaining body into memory or block the event loop.","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-400","package","python","self-hosted"],"not_affected_if":["fixed-version","no-multipart-handlers"],"how_to_check":"- Check the installed version with `pip show aiohttp` and see whether it is `3.14.3` or older.\n- Look for handlers that call `multipart()` or read `BodyPartReader` data from request bodies.","fix":"- `aiohttp` `3.14.4`","status":"open","published_at":"2026-11-08T18:23:00+00:00","first_seen_at":"2026-11-09T22:53:22+00:00","triaged_at":"2026-11-09T22:58:35+00:00","updated_at":"2026-11-09T22:58:35+00:00","category":"package","confidence":0.8,"triage":{"at":"2026-11-09T22:58:35Z","model":"claude-haiku-5-5","output":{"fix":"- `aiohttp` `3.14.4`","reach":"internet","title":"aiohttp: base64 multipart parts bypass request size limit, exhausting memory","impact":"medium","summary":"aiohttp's multipart reader keeps reading base64-encoded parts without a byte limit until the chunk length is a multiple of four. A crafted multipart request can make the server load the whole remaining body into memory or block the event loop.","audience":"developers","category":"package","nicknames":[],"who_cares":["python","aiohttp","self-hosted"],"confidence":0.8,"fix_status":"available","needs_auth":"no","worst_case":"Attacker exhausts server memory or stalls the event loop with one request","analyst_note":"","how_to_check":"- Check the installed version with `pip show aiohttp` and see whether it is `3.14.3` or older.\n- Look for handlers that call `multipart()` or read `BodyPartReader` data from request bodies.","plain_action":"","product_name":"","needs_analyst":false,"not_affected_if":["no-multipart-handlers","fixed-version"],"who_is_affected":"Applications built on aiohttp that accept multipart uploads through a request handler are exposed, because the flaw is in how the multipart reader decodes base64 parts. Services that do not read multipart request bodies, or that run an aiohttp version above 3.14.3, can skip it.","user_interaction":"no","product_ecosystem":"","needs_special_setup":"no","severity_if_unknown":"medium"},"cost_usd":0.000728,"input_tokens":4753,"output_tokens":506,"severity_before":"medium"},"analyst_status":null,"analyst_note":null,"search":"'-400':21B '/aio-libs/aiohttp/commit/a555ab698e08e9baea7386d5b4c0761cb8956fdd':172C '24c4':10A,15A '29cm':12A,17A '3p7v':11A,16A '4':94C 'aiohttp':18A,19B,27B 'attack':140C 'base64':1A,34B,81C 'base64-encoded':33B 'block':66B,152C 'bodi':62B,118C 'bodypartreader.read':82C 'bypass':4A,142C 'byte':39B,97C 'call':127C 'caus':114C,147C 'check':131C 'chunk':43B,83C,88C 'client':5A,143C 'content':78C,105C 'content-length':104C 'content-transfer-encod':77C 'could':113C,141C 'craft':51B,159C 'cwe':20B 'data':168C 'encod':35B,80C 'entir':116C 'event':68B,136C,154C 'excess':148C 'four':49B 'ghsa':9A,14A 'ghsa-24c4-3p7v-29cm':8A,13A 'github.com':171C 'github.com/aio-libs/aiohttp/commit/a555ab698e08e9baea7386d5b4c0761cb8956fdd':170C 'handler':164C 'host':26B 'impact':138C 'keep':31B 'kept':84C 'length':44B,89C,106C 'limit':40B,98C 'load':58B 'long':109C 'loop':69B,137C,155C 'make':55B 'max':6A,144C 'memori':64B,123C,149C 'multipart':2A,29B,52B,74C,160C,167C 'multipl':47B,92C 'packag':22B 'part':3A,36B,75C,100C 'patch':169C 'python':23B 'read':32B,72C,85C,121C,166C 'reader':30B 'remain':61B,117C 'request':53B,161C 'run':110C 'self':25B 'self-host':24B 'server':57B 'short':103C 'singl':126C 'size':7A,130C,145C 'special':158C 'spin':133C 'summari':70C 'transfer':79C 'use':150C 'whitespac':112C 'whole':60B 'within':124C 'without':37B","nicknames":[],"mitigations":[],"who_affected":"Applications built on aiohttp that accept multipart uploads through a request handler are exposed, because the flaw is in how the multipart reader decodes base64 parts. Services that do not read multipart request bodies, or that run an aiohttp version above 3.14.3, can skip it.","tier":"C","verified":{},"analyst_revisit_at":null,"fix_status":"available","audience":"developers","plain_action":null,"pkeys":["aiohttp"],"ptokens":["aiohttp"],"labels":["aiohttp","cwe400","medium","package","pypi","python","selfhosted"],"campaign_type":null,"search_a":"'24c4':10A,15A '29cm':12A,17A '3p7v':11A,16A 'aiohttp':18A 'base64':1A 'bypass':4A 'client':5A 'ghsa':9A,14A 'ghsa-24c4-3p7v-29cm':8A,13A 'max':6A 'multipart':2A 'part':3A 'size':7A","search_b":"'-400':21B 'aiohttp':19B,27B 'base64':34B 'base64-encoded':33B 'block':66B 'bodi':62B 'byte':39B 'chunk':43B 'craft':51B 'cwe':20B 'encod':35B 'event':68B 'four':49B 'host':26B 'keep':31B 'length':44B 'limit':40B 'load':58B 'loop':69B 'make':55B 'memori':64B 'multipart':29B,52B 'multipl':47B 'packag':22B 'part':36B 'python':23B 'read':32B 'reader':30B 'remain':61B 'request':53B 'self':25B 'self-host':24B 'server':57B 'whole':60B 'without':37B","search_c":"'/aio-libs/aiohttp/commit/a555ab698e08e9baea7386d5b4c0761cb8956fdd':172C '4':94C 'attack':140C 'base64':81C 'block':152C 'bodi':118C 'bodypartreader.read':82C 'bypass':142C 'byte':97C 'call':127C 'caus':114C,147C 'check':131C 'chunk':83C,88C 'client':143C 'content':78C,105C 'content-length':104C 'content-transfer-encod':77C 'could':113C,141C 'craft':159C 'data':168C 'encod':80C 'entir':116C 'event':136C,154C 'excess':148C 'github.com':171C 'github.com/aio-libs/aiohttp/commit/a555ab698e08e9baea7386d5b4c0761cb8956fdd':170C 'handler':164C 'impact':138C 'kept':84C 'length':89C,106C 'limit':98C 'long':109C 'loop':137C,155C 'max':144C 'memori':123C,149C 'multipart':74C,160C,167C 'multipl':92C 'part':75C,100C 'patch':169C 'read':72C,85C,121C,166C 'remain':117C 'request':161C 'run':110C 'short':103C 'singl':126C 'size':130C,145C 'special':158C 'spin':133C 'summari':70C 'transfer':79C 'use':150C 'whitespac':112C 'within':124C","cause_entry":null,"cause_path":null,"disclosures_checked_at":null,"first_public_at":"2026-11-08T18:23:00+00:00","kev":null,"cvss_vector":null,"cvss_by":null,"poc_count":0,"sources":[{"source":"ghsa-repo","external_id":"GHSA-24c4-3p7v-29cm","url":"https://github.com/aio-libs/aiohttp/security/advisories/GHSA-24c4-3p7v-29cm","severity":"medium","published_at":"2026-11-08T18:23:00+00:00","modified_at":"2026-11-08T18:42:19+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":110553,"url":"https://github.com/aio-libs/aiohttp/security/advisories/GHSA-24c4-3p7v-29cm","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"}