Summary
Quarkus REST / RESTEasy Reactive's MultipartParser accumulates MIME part-header bytes without any size or count limit. An unauthenticated remote attacker can send a single crafted multipart/form-data request with an arbitrarily large part-header section to exhaust the JVM heap and crash the application.
Details
The MultipartParser state machine reads part-header bytes (header names and values within each MIME part) into ByteArrayOutputStream (currentString) with no upper bound. The existing maxEntitySize guard only counts body bytes delivered through the data() callback; header bytes bypass it entirely.
On the non-blocking parse path (VertxResteasyReactiveRequestContext.setReadListener()), there is no wire-byte cap. An attacker can send a chunked Transfer-Encoding: chunked request containing a single MIME part with a multi-gigabyte header value (e.g. X-Boom: <4GB of data>). The parser will faithfully buffer the entire value in memory before any application code runs, leading to OutOfMemoryError.
The attack requires no authentication or valid form field names and works against any endpoint that accepts multipart/form-data.
Impact
Denial of service. A single HTTP request can crash the JVM with OutOfMemoryError. No data exfiltration or code execution is possible through this vector.
Patches
Fixed by adding per-part header size and header count limits to MultipartParser. Requests exceeding the limits are rejected with HTTP 413 (Request Entity Too Large).
The thresholds are configurable:
- quarkus.http.limits.max-multipart-part-header-size (default: 32KB)
- quarkus.http.limits.max-multipart-header-count (default: 40)
Workarounds
No effective workaround exists. Reverse-proxy header-size limits typically apply to HTTP request headers, not to MIME part headers embedded within the request body.
References
- CWE-770: Allocation of Resources Without Limits or Throttling
Summary
Quarkus REST / RESTEasy Reactive's MultipartParser accumulates MIME part-header bytes without any size or count limit. An unauthenticated remote attacker can send a single crafted multipart/form-data request with an arbitrarily large part-header section to exhaust the JVM heap and crash the application.
Details
The MultipartParser state machine reads part-header bytes (header names and values within each MIME part) into ByteArrayOutputStream (currentString) with no upper bound. The existing maxEntitySize guard only counts body bytes delivered through the data() callback; header bytes bypass it entirely.
On the non-blocking parse path (VertxResteasyReactiveRequestContext.setReadListener()), there is no wire-byte cap. An attacker can send a chunked Transfer-Encoding: chunked request containing a single MIME part with a multi-gigabyte header value (e.g. X-Boom: <4GB of data>). The parser will faithfully buffer the entire value in memory before any application code runs, leading to OutOfMemoryError.
The attack requires no authentication or valid form field names and works against any endpoint that accepts multipart/form-data.
Impact
Denial of service. A single HTTP request can crash the JVM with OutOfMemoryError. No data exfiltration or code execution is possible through this vector.
Patches
Fixed by adding per-part header size and header count limits to MultipartParser. Requests exceeding the limits are rejected with HTTP 413 (Request Entity Too Large).
The thresholds are configurable:
Workarounds
No effective workaround exists. Reverse-proxy header-size limits typically apply to HTTP request headers, not to MIME part headers embedded within the request body.
References