CVE-2026-10050
ADVISORY - githubSummary
Summary
The DigestAuthentication.apply() method in Jetty's HTTP client uses getBytes(StandardCharsets.ISO_8859_1) at three locations (lines 171, 179, 196) to compute Digest auth response hashes. ISO-8859-1 silently replaces any character above U+00FF (Chinese, Japanese, Cyrillic, Arabic, Emoji, etc.) with 0x3F (?), causing all such characters to produce identical hash contributions. An attacker who knows a victim's username can bypass Digest authentication by replacing all non-Latin-1 characters in the password with ? characters, since the collision password produces the same MD5-based Digest response hash as the original password.
Details
Root Cause
In jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/DigestAuthentication.java, the apply() method computes the three Digest auth hashes (H(A1), H(A2), and the final response) using ISO-8859-1 character encoding:
// Line 171 — H(A1)
String hashA1 = toHexString(digester.digest(a1.getBytes(StandardCharsets.ISO_8859_1)));
// Line 179 — H(A2)
String hashA2 = toHexString(digester.digest(a2.getBytes(StandardCharsets.ISO_8859_1)));
// Line 196 — Final response hash
final String hashA3 = toHexString(digester.digest(a3.getBytes(StandardCharsets.ISO_8859_1)));
ISO-8859-1 (Latin-1) can only encode characters in the range U+0000–U+00FF. Any character outside this range — including all CJK, Cyrillic, Arabic, Greek, Hangul, and emoji characters — is silently replaced with the byte 0x3F (?). String.getBytes(ISO_8859_1) in Java performs this replacement without any warning or exception.
PoC
Password: "我爱Java!密码123★" (7 non-Latin-1 characters)
UTF-8 encoding: 45 bytes → MD5 H(A1) = 9a4e61484f228633d5d0f95d1bbb0a99
ISO-8859-1: 31 bytes → MD5 H(A1) = d60ddc903d71913bcc3ab4a94f7fc239
Collision "??...": 31 bytes → MD5 H(A1) = d60ddc903d71913bcc3ab4a94f7fc239 ← IDENTICAL
Multi-language confirmation — all four language passwords below produce the same hash:
Chinese (密码123) → H(A1) = db87f31e8d96cd15f9acec7eabdc4560
Korean (비번123) → H(A1) = db87f31e8d96cd15f9acec7eabdc4560
Cyrillic(аб123) → H(A1) = db87f31e8d96cd15f9acec7eabdc4560
Greek (αβ123) → H(A1) = db87f31e8d96cd15f9acec7eabdc4560
Attacker(??123) → H(A1) = db87f31e8d96cd15f9acec7eabdc4560 ← all collide!
Impact
Scenario 1: Authentication Bypass (Collision Attack)
If a service using Jetty for Digest authentication has a user with a non-Latin-1 password (e.g., Chinese, Japanese, Russian), an attacker can authenticate as that user using a collision password where all non-Latin-1 characters are replaced with ?:
- Original password:
我爱Java!密码123★ - Collision password:
??Java!??123? - Both produce identical MD5 hashes under ISO-8859-1 → Authentication succeeds
This affects any password containing characters > U+00FF, which covers:
- Chinese (CJK): U+4E00–U+9FFF
- Japanese (Hiragana/Katakana/Kanji): U+3040–U+30FF, U+4E00+
- Korean (Hangul): U+AC00–U+D7AF
- Cyrillic: U+0400–U+04FF (Russian, Ukrainian, Bulgarian, etc.)
- Arabic: U+0600–U+06FF
- Greek: U+0370–U+03FF
- Latin Extended: U+0100–U+024F (accented European characters like ĉ, ğ, ñ when > U+00FF)
- Emoji / Symbols > U+00FF
Scenario 2: Denial of Service for Non-Latin-1 Users
Most modern web applications store password hashes computed using UTF-8. When Jetty's Digest client computes a hash with ISO-8859-1, the bytes differ from what the server stored/expects. This means any user with non-ASCII (Latin-1+) characters in their password can never successfully authenticate via Digest auth — even the legitimate user. This is not just a security issue but a functional correctness bug that silently breaks authentication for most non-European-language users.
NIST
CVSS SCORE
8.7highGitHub
CVSS SCORE
8.7highDebian
-
Ubuntu
3.9
CVSS SCORE
9.1mediumChainguard
CGA-mhwc-69g2-8cp8
-
minimos
MINI-265w-f72r-4q43
-
minimos
MINI-26fr-3fhj-8cmc
-
minimos
MINI-2gwc-h7rv-fgj2
-
minimos
MINI-4mpv-646q-ccwf
-
minimos
MINI-5334-6743-j6wv
-
minimos
MINI-5q4q-vr2h-78cp
-
minimos
MINI-6fjw-36r5-422h
-
minimos
MINI-79f6-2m7j-xh5g
-
minimos
MINI-7g63-xqq3-2x38
-
minimos
MINI-8wmc-4gqj-29xx
-
minimos
MINI-93pf-x7cx-jjqp
-
minimos
MINI-94cr-pr28-v538
-
minimos
MINI-984x-vqw5-cx5h
-
minimos
MINI-9mj8-6hcq-5qvp
-
minimos
MINI-c2mx-p8jh-44gm
-
minimos
MINI-c5h6-9v9p-8ghm
-
minimos
MINI-c62r-wwwx-hmc3
-
minimos
MINI-cc7c-9jjq-277q
-
minimos
MINI-f2xj-qxf3-84rp
-
minimos
MINI-f79j-fvrx-3cmj
-
minimos
MINI-fc8h-fmw8-qxgm
-
minimos
MINI-fcpg-v2wq-65wq
-
minimos
MINI-fjqg-p4jg-4g94
-
minimos
MINI-g6h8-29gv-gfvh
-
minimos
MINI-g6vf-6f6w-p758
-
minimos
MINI-g8rf-vm3w-4cjr
-
minimos
MINI-gh3p-x38p-9q93
-
minimos
MINI-gq7m-g6gc-pg9q
-
minimos
MINI-gq9m-4j5c-8vvj
-
minimos
MINI-grg2-9r4g-mcrr
-
minimos
MINI-h56x-2f4c-92p5
-
minimos
MINI-h7f9-pvqh-cgfm
-
minimos
MINI-hrv7-hrg9-4rx5
-
minimos
MINI-j663-hxx7-9vgq
-
minimos
MINI-j6wr-f7m4-ff59
-
minimos
MINI-j9qj-8gq6-j64v
-
minimos
MINI-jqqx-f232-2rwq
-
minimos
MINI-jw54-7qm3-q65j
-
minimos
MINI-p8vp-c56c-6jcq
-
minimos
MINI-pqgc-52jg-227v
-
minimos
MINI-qjrr-fj8c-4hfq
-
minimos
MINI-qp43-cc33-h7pf
-
minimos
MINI-rjx6-293p-xvcg
-
minimos
MINI-rpr4-x532-685r
-
minimos
MINI-vf85-95f9-mxhc
-
minimos
MINI-w863-j5w4-2698
-
minimos
MINI-w9h3-w57c-hr6r
-
minimos
MINI-x3f9-8576-p2q5
-
minimos
MINI-x5p3-fc87-2gfg
-
minimos
MINI-xx94-5vfg-5vch
-