CVE-2026-69205: http4s Ember Transfer-Encoding Case-Sensitive Parsing HTTP Request Smuggling
http4s Ember compared the Transfer-Encoding header value with a case-sensitive substring match, so a value like 'Chunked' (capital C) was silently ignored, letting an attacker trick a front-end proxy…

The problem
Ember's HTTP/1.1 header parser in HeaderP.parse checked for chunked encoding using hValue.contains("chunked"), a case-sensitive substring test. RFC 9112 §7 requires transfer-coding names to be compared case-insensitively.
When Ember received Transfer-Encoding: Chunked, it did not recognise the value as chunked and fell back to framing by Content-Length (or zero if absent). A compliant intermediary in front of Ember would correctly treat the same request as chunked-encoded. The two parsers disagreed on message boundaries, enabling TE.CL and TE.0 request smuggling.
The same bug also admitted two further variants: the substring test fired on Transfer-Encoding: notchunked (inverse desync), and a Unicode Kelvin Sign (U+212A) could bypass the comparison once case-folding was applied.
Proof of concept
A working proof-of-concept for CVE-2026-69205 in org.http4s:http4s-ember-core_3, with the exact payload below.
POST /admin HTTP/1.1
Host: internal-app
Transfer-Encoding: Chunked
Content-Length: 4
1
Z
0
GET /private HTTP/1.1
Host: internal-app
Foo: barThe front-end proxy sees Transfer-Encoding: Chunked and correctly frames the body as chunked (per RFC 9112), reading up to and including the terminating 0\r\n\r\n chunk. Ember's case-sensitive hValue.contains("chunked") test misses the capital-C value, so Ember falls back to Content-Length: 4 and reads exactly 4 bytes (1\r\nZ).
The remaining bytes, starting with GET /private, stay in Ember's read buffer and are prepended to the next pipelined or pooled request, smuggling it as an attacker-controlled request.
The patch replaces the raw substring test with a proper case-insensitive, RFC-compliant token comparison (CWE-444). After the fix, Chunked, CHUNKED, and any other capitalisation are all normalised before the check, closing all three variants described in the advisory.
The fix
Upgrade to org.http4s:http4s-ember-core_3 version **0.23.35** (or **1.0.0-M47** on the 1.x milestone series). The fix is in commit 5e88b2e7b4e6ea2f0c61040a4bc9de0d73e51217. If you cannot upgrade immediately, place a normalising intermediary in front of Ember that either fully buffers and re-encodes request bodies (nginx proxy_request_buffering on is the default), lowercases the Transfer-Encoding token before forwarding, or disables backend keep-alive so smuggled prefixes cannot bleed into the next connection.
Reported by reardonj and ERobertGII (security analysis and mitigations, acknowledged by Ross A. Baker).
Related research
- criticalCVE-2026-69204CVE-2026-69204: http4s Ember CL.TE HTTP Request Smuggling
- high · 7.4http4s-blaze-server HTTP/1.1 Request Smuggling (Multiple Parser Laxities)
- high · 7.4blaze-server HTTP/1.1 Chunked Trailer Header Injection
- high · 7.5CVE-2026-69202CVE-2026-69202: http4s Ember HTTP/2 Unbounded Inbound Body Buffering DoS