CVE-2026-69205
Http4s: Ember Transfer-Encoding value parsing (TE.CL / TE.0 request smuggling)
Http4s is a Scala interface for HTTP services. Prior to 0.23.35 and 1.0.0-M47, Ember’s HeaderP.parse uses a case-sensitive substring test for the Transfer-Encoding value and decodes header bytes with the platform default charset. Values such as Chunked are not recognized, values such as notchunked are incorrectly accepted, and Unicode case folding can turn a Kelvin-sign byte sequence into a match when UTF-8 is used. Intermediaries that apply RFC-compliant token and charset rules can therefore disagree with Ember’s Content-Length or zero-length framing, enabling TE.CL or TE.0 request smuggling, access-control bypass, cross-user request hijacking, and cache poisoning on the server path. Response smuggling through an ember-client gateway requires a malicious or compromised upstream. This issue is fixed in versions 0.23.35 and 1.0.0-M47.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- High
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- High
- Integrity
- High
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
8.7
Http4s: Ember Transfer-Encoding value parsing (TE.CL / TE.0 request smuggling)
Http4s is a Scala interface for HTTP services. Prior to 0.23.35 and 1.0.0-M47, Ember’s HeaderP.parse uses a case-sensitive substring test for the Transfer-Encoding value and decodes header bytes with the platform default charset. Values such as Chunked are not recognized, values such as notchunked are incorrectly accepted, and Unicode case folding can turn a Kelvin-sign byte sequence into a match when UTF-8 is used. Intermediaries that apply RFC-compliant token and charset rules can therefore disagree with Ember’s Content-Length or zero-length framing, enabling TE.CL or TE.0 request smuggling, access-control bypass, cross-user request hijacking, and cache poisoning on the server path. Response smuggling through an ember-client gateway requires a malicious or compromised upstream. This issue is fixed in versions 0.23.35 and 1.0.0-M47.
- Record
CVE-2026-69205- CVSS 3.1
- 8.7 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:N - Weakness
- CWE-444
- Updated
- 2026-11-02
EUVDEUVD-2026-79190
8.7
Http4s is a Scala interface for HTTP services. Prior to 0.23.35 and 1.0.0-M47, Ember’s HeaderP.parse uses a case-sensitive substring test for the Transfer-Encoding value and decodes header bytes with the platform default charset. Values such as Chunked are not recognized, values such as notchunked are incorrectly accepted, and Unicode case folding can turn a Kelvin-sign byte sequence into a match when UTF-8 is used. Intermediaries that apply RFC-compliant token and charset rules can therefore disagree with Ember’s Content-Length or zero-length framing, enabling TE.CL or TE.0 request smuggling, access-control bypass, cross-user request hijacking, and cache poisoning on the server path. Response smuggling through an ember-client gateway requires a malicious or compromised upstream. This issue is fixed in versions 0.23.35 and 1.0.0-M47.
- Record
EUVD-2026-79190- CVSS 3.1
- 8.7 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-9998-894r-fwvr
8.7
Http4s Ember Transfer-Encoding value parsing (TE.CL / TE.0 request smuggling)
Summary
Ember's HTTP/1.1 header parser matches the Transfer-Encoding header value
with a case-sensitive substring test (hValue.contains("chunked")). RFC
9112 §7 requires transfer-coding names to be compared case-insensitively. A
request carrying Transfer-Encoding: Chunked (capital C) is therefore not
recognised as chunked, and Ember falls back to framing by Content-Length
(or zero if absent) while a compliant intermediary frames the same bytes by
chunked encoding. The two parsers then disagree on where the request body
ends, enabling HTTP request smuggling (TE.CL / TE.0).
The same line of code admits two further variants:
- The substring test misfires on
Transfer-Encoding: notchunked(an inverse desync — Ember treats it as chunked while a compliant intermediary rejects the unknown coding). - Header field bytes are decoded with the platform-default charset. Under
UTF-8 the wire bytes
E2 84 AAdecode to U+212A KELVIN SIGN, whichString.equalsIgnoreCaseUnicode-case-folds tok, soTransfer-Encoding: chun<U+212A>edmatcheschunkedonce the comparison is made case-insensitive without also pinning the decode to ISO-8859-1.
Impact
Server
Request smuggling when ember-server is an origin behind an intermediary that
honours Transfer-Encoding case-insensitively per RFC, forwards the header
value verbatim, and reuses keep-alive connections to the backend:
- Front-end security bypass: the smuggled request reaches paths the intermediary's ACL/auth layer would have blocked, with attacker-chosen method and headers.
- Cross-user request hijack: a partial smuggled prefix left in Ember's
connection buffer is concatenated with the next victim's request on the
same pooled backend connection, exposing its headers (e.g.
Cookie,Authorization) to the attacker. - Cache poisoning: the smuggled response is associated with the next request key in a caching proxy.
Client
ember-client shares the same HeaderP.parse on the response path, enabling
response smuggling when http4s is used as a gateway. This is less severe: it
requires a malicious or compromised upstream rather than an anonymous remote
client.
Preconditions
- Unauthenticated remote attacker (server)
- ember-server as origin behind a keep-alive intermediary
- Intermediary treats
Transfer-Encodingcase-insensitively (per RFC) and forwards the header value without lowercasing it - Malicious or compromised upstream (client)
Workarounds
- Intermediary fully buffers and re-encodes request bodies (e.g. nginx with
default
proxy_request_buffering on) - Intermediary normalises the
Transfer-Encodingvalue (lowercases the token) before forwarding - Disable backend keep-alive between the intermediary and Ember
- Record
GHSA-9998-894r-fwvr- CVSS 3.1
- 8.7 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:N - Weakness
- CWE-444
- Updated
- 2026-11-02
NVD
8.7
Http4s is a Scala interface for HTTP services. Prior to 0.23.35 and 1.0.0-M47, Ember’s HeaderP.parse uses a case-sensitive substring test for the Transfer-Encoding value and decodes header bytes with the platform default charset. Values such as Chunked are not recognized, values such as notchunked are incorrectly accepted, and Unicode case folding can turn a Kelvin-sign byte sequence into a match when UTF-8 is used. Intermediaries that apply RFC-compliant token and charset rules can therefore disagree with Ember’s Content-Length or zero-length framing, enabling TE.CL or TE.0 request smuggling, access-control bypass, cross-user request hijacking, and cache poisoning on the server path. Response smuggling through an ember-client gateway requires a malicious or compromised upstream. This issue is fixed in versions 0.23.35 and 1.0.0-M47.
- Record
CVE-2026-69205- CVSS 3.1
- 8.7 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:N - Weakness
- CWE-444
- Updated
- 2026-11-02
OSV
8.7
Http4s: Ember Transfer-Encoding value parsing (TE.CL / TE.0 request smuggling)
Http4s is a Scala interface for HTTP services. Prior to 0.23.35 and 1.0.0-M47, Ember’s HeaderP.parse uses a case-sensitive substring test for the Transfer-Encoding value and decodes header bytes with the platform default charset. Values such as Chunked are not recognized, values such as notchunked are incorrectly accepted, and Unicode case folding can turn a Kelvin-sign byte sequence into a match when UTF-8 is used. Intermediaries that apply RFC-compliant token and charset rules can therefore disagree with Ember’s Content-Length or zero-length framing, enabling TE.CL or TE.0 request smuggling, access-control bypass, cross-user request hijacking, and cache poisoning on the server path. Response smuggling through an ember-client gateway requires a malicious or compromised upstream. This issue is fixed in versions 0.23.35 and 1.0.0-M47.
- Record
CVE-2026-69205- CVSS 3.1
- 8.7 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:N - Weakness
- CWE-444
- Updated
- 2026-11-02
OSVGHSA-9998-894r-fwvr
8.7
Http4s Ember Transfer-Encoding value parsing (TE.CL / TE.0 request smuggling)
Summary
Ember's HTTP/1.1 header parser matches the Transfer-Encoding header value
with a case-sensitive substring test (hValue.contains("chunked")). RFC
9112 §7 requires transfer-coding names to be compared case-insensitively. A
request carrying Transfer-Encoding: Chunked (capital C) is therefore not
recognised as chunked, and Ember falls back to framing by Content-Length
(or zero if absent) while a compliant intermediary frames the same bytes by
chunked encoding. The two parsers then disagree on where the request body
ends, enabling HTTP request smuggling (TE.CL / TE.0).
The same line of code admits two further variants:
- The substring test misfires on
Transfer-Encoding: notchunked(an inverse desync — Ember treats it as chunked while a compliant intermediary rejects the unknown coding). - Header field bytes are decoded with the platform-default charset. Under
UTF-8 the wire bytes
E2 84 AAdecode to U+212A KELVIN SIGN, whichString.equalsIgnoreCaseUnicode-case-folds tok, soTransfer-Encoding: chun<U+212A>edmatcheschunkedonce the comparison is made case-insensitive without also pinning the decode to ISO-8859-1.
Impact
Server
Request smuggling when ember-server is an origin behind an intermediary that
honours Transfer-Encoding case-insensitively per RFC, forwards the header
value verbatim, and reuses keep-alive connections to the backend:
- Front-end security bypass: the smuggled request reaches paths the intermediary's ACL/auth layer would have blocked, with attacker-chosen method and headers.
- Cross-user request hijack: a partial smuggled prefix left in Ember's
connection buffer is concatenated with the next victim's request on the
same pooled backend connection, exposing its headers (e.g.
Cookie,Authorization) to the attacker. - Cache poisoning: the smuggled response is associated with the next request key in a caching proxy.
Client
ember-client shares the same HeaderP.parse on the response path, enabling
response smuggling when http4s is used as a gateway. This is less severe: it
requires a malicious or compromised upstream rather than an anonymous remote
client.
Preconditions
- Unauthenticated remote attacker (server)
- ember-server as origin behind a keep-alive intermediary
- Intermediary treats
Transfer-Encodingcase-insensitively (per RFC) and forwards the header value without lowercasing it - Malicious or compromised upstream (client)
Workarounds
- Intermediary fully buffers and re-encodes request bodies (e.g. nginx with
default
proxy_request_buffering on) - Intermediary normalises the
Transfer-Encodingvalue (lowercases the token) before forwarding - Disable backend keep-alive between the intermediary and Ember
- Record
GHSA-9998-894r-fwvr- CVSS 3.1
- 8.7 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:N - Weakness
- CWE-444
- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
org.http4s:http4s-ember-core_3Maven |
through 0.23.34 | 0.23.35 |
org.http4s:http4s-ember-core_2.13Maven |
through 0.23.34 | 0.23.35 |
org.http4s:http4s-ember-core_2.12Maven |
through 0.23.34 | 0.23.35 |
org.http4s:http4s-ember-core_2.13Maven |
1.0.0-M1 to 1.0.0-M46 | 1.0.0-M47 |
org.http4s:http4s-ember-core_3Maven |
1.0.0-M1 to 1.0.0-M46 | 1.0.0-M47 |
org.http4s:http4s-ember-core_3Maven |
before 0.23.35, plus listed versions 0.22.00.22.0-M80.22.0-RC10.22.10.22.10 Show 45 moreShow less0.22.110.22.120.22.130.22.140.22.150.22.20.22.30.22.40.22.50.22.60.22.70.22.80.22.90.23.00.23.0-M10.23.0-RC10.23.10.23.100.23.110.23.120.23.130.23.140.23.150.23.160.23.170.23.180.23.190.23.19-RC10.23.19-RC20.23.19-RC30.23.20.23.200.23.210.23.220.23.230.23.240.23.250.23.260.23.270.23.280.23.290.23.30.23.300.23.310.23.32 |
0.23.35 |
org.http4s:http4s-ember-core_2.13Maven |
before 0.23.35, plus listed versions 0.10.0-M100.21.00.21.0-M20.21.0-M30.21.0-M4 Show 45 moreShow less0.21.0-M50.21.0-M60.21.0-RC10.21.0-RC20.21.0-RC30.21.0-RC40.21.0-RC50.21.10.21.110.21.120.21.130.21.140.21.150.21.160.21.170.21.180.21.190.21.20.21.200.21.210.21.220.21.230.21.240.21.250.21.260.21.270.21.280.21.290.21.30.21.300.21.310.21.320.21.330.21.340.21.40.21.50.21.60.21.70.21.80.21.90.22-129-24d065b0.22-143-49b5a8d0.22-53-01128f50.22-96-55d31840.22.0 |
0.23.35 |
org.http4s:http4s-ember-core_2.12Maven |
before 0.23.35, plus listed versions 0.10.0-M100.21.00.21.0-M20.21.0-M30.21.0-M4 Show 45 moreShow less0.21.0-M50.21.0-M60.21.0-RC10.21.0-RC20.21.0-RC30.21.0-RC40.21.0-RC50.21.10.21.110.21.120.21.130.21.140.21.150.21.160.21.170.21.180.21.190.21.20.21.200.21.210.21.220.21.230.21.240.21.250.21.260.21.270.21.280.21.290.21.30.21.300.21.310.21.320.21.330.21.340.21.40.21.50.21.60.21.70.21.80.21.90.22-129-24d065b0.22-143-49b5a8d0.22-53-01128f50.22-96-55d31840.22.0 |
0.23.35 |
org.http4s:http4s-ember-core_2.13Maven |
1.0.0-M1 up to 1.0.0-M47, plus listed versions 1.0.0-M101.0.0-M111.0.0-M131.0.0-M141.0.0-M15 Show 38 moreShow less1.0.0-M161.0.0-M171.0.0-M181.0.0-M191.0.0-M21.0.0-M201.0.0-M211.0.0-M221.0.0-M231.0.0-M241.0.0-M251.0.0-M271.0.0-M281.0.0-M291.0.0-M31.0.0-M301.0.0-M311.0.0-M321.0.0-M331.0.0-M341.0.0-M351.0.0-M361.0.0-M371.0.0-M381.0.0-M391.0.0-M41.0.0-M401.0.0-M411.0.0-M421.0.0-M431.0.0-M441.0.0-M451.0.0-M461.0.0-M51.0.0-M61.0.0-M71.0.0-M81.0.0-M9 |
1.0.0-M47 |
org.http4s:http4s-ember-core_3Maven |
1.0.0-M1 up to 1.0.0-M47, plus listed versions 1.0.0-M221.0.0-M231.0.0-M241.0.0-M251.0.0-M27 Show 19 moreShow less1.0.0-M281.0.0-M291.0.0-M301.0.0-M311.0.0-M321.0.0-M331.0.0-M341.0.0-M351.0.0-M361.0.0-M371.0.0-M381.0.0-M391.0.0-M401.0.0-M411.0.0-M421.0.0-M431.0.0-M441.0.0-M451.0.0-M46 |
1.0.0-M47 |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-69205 is a high vulnerability (CVSS 8.7) in Http4s, published September 15, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.48%, the 41st percentile. Fixed in org.http4s:http4s-ember-core_3 0.23.35.
References
github.com/http4s/http4s/security/advisories/GHSA-9998-894r-fwvr
github.com/http4s/http4s/commit/5e88b2e7b4e6ea2f0c61040a4bc9de0d73e51217
github.com/http4s/http4s/releases/tag/v0.23.35
github.com/http4s/http4s/releases/tag/v1.0.0-M47
github.com/advisories/GHSA-9998-894r-fwvr
github.com/CVEProject/cvelistV5/tree/main/cves/2026/69xxx/CVE-2026-69205.json
nvd.nist.gov/vuln/detail/CVE-2026-69205
github.com/http4s/http4s
Left out here: 136 versions. The JSON record has them.