{"id":"CVE-2026-10050","aliases":["GHSA-2fvj-hgj9-j2gr"],"url":"https://o3.security/vulnerability/CVE-2026-10050","summary":"Digest authentication lossy encoding","details":"### Summary\nThe `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.\n\n### Details\n### Root Cause\n\nIn `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:\n\n```java\n// Line 171 — H(A1)\nString hashA1 = toHexString(digester.digest(a1.getBytes(StandardCharsets.ISO_8859_1)));\n\n// Line 179 — H(A2)\nString hashA2 = toHexString(digester.digest(a2.getBytes(StandardCharsets.ISO_8859_1)));\n\n// Line 196 — Final response hash\nfinal String hashA3 = toHexString(digester.digest(a3.getBytes(StandardCharsets.ISO_8859_1)));\n```\n\nISO-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.\n\n### PoC\n```\nPassword: \"我爱Java!密码123★\" (7 non-Latin-1 characters)\n\nUTF-8 encoding:    45 bytes → MD5 H(A1) = 9a4e61484f228633d5d0f95d1bbb0a99\nISO-8859-1:        31 bytes → MD5 H(A1) = d60ddc903d71913bcc3ab4a94f7fc239\nCollision \"??...\": 31 bytes → MD5 H(A1) = d60ddc903d71913bcc3ab4a94f7fc239 ← IDENTICAL\n```\n\nMulti-language confirmation — all four language passwords below produce the same hash:\n\n```\nChinese (密码123)  → H(A1) = db87f31e8d96cd15f9acec7eabdc4560\nKorean  (비번123)  → H(A1) = db87f31e8d96cd15f9acec7eabdc4560\nCyrillic(аб123)    → H(A1) = db87f31e8d96cd15f9acec7eabdc4560\nGreek   (αβ123)    → H(A1) = db87f31e8d96cd15f9acec7eabdc4560\nAttacker(??123)    → H(A1) = db87f31e8d96cd15f9acec7eabdc4560 ← all collide!\n```\n\n### Impact\n**Scenario 1: Authentication Bypass (Collision Attack)**\n\nIf 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 `?`:\n\n- Original password: `我爱Java!密码123★`\n- Collision password: `??Java!??123?`\n- **Both produce identical MD5 hashes under ISO-8859-1** → Authentication succeeds\n\nThis affects any password containing characters > U+00FF, which covers:\n- Chinese (CJK): U+4E00–U+9FFF\n- Japanese (Hiragana/Katakana/Kanji): U+3040–U+30FF, U+4E00+\n- Korean (Hangul): U+AC00–U+D7AF\n- Cyrillic: U+0400–U+04FF (Russian, Ukrainian, Bulgarian, etc.)\n- Arabic: U+0600–U+06FF\n- Greek: U+0370–U+03FF\n- Latin Extended: U+0100–U+024F (accented European characters like ĉ, ğ, ñ when > U+00FF)\n- Emoji / Symbols > U+00FF\n\n**Scenario 2: Denial of Service for Non-Latin-1 Users**\n\nMost 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.","published":"2026-08-04T11:02:40.503Z","modified":"2026-10-24T10:30:47.924896376Z","cvss":null,"epss":{"score":0.00483,"percentile":0.40592,"asOf":"2026-09-17"},"cisaKev":null,"exploitsKnown":0,"affectedPackages":[{"ecosystem":"Maven","name":"org.eclipse.jetty:jetty-security","fixedVersion":"9.4.63"},{"ecosystem":"Maven","name":"org.eclipse.jetty:jetty-security","fixedVersion":"10.0.31"},{"ecosystem":"Maven","name":"org.eclipse.jetty:jetty-security","fixedVersion":"11.0.31"},{"ecosystem":"Maven","name":"org.eclipse.jetty:jetty-security","fixedVersion":"12.0.36"},{"ecosystem":"Maven","name":"org.eclipse.jetty.ee8:jetty-ee8-security","fixedVersion":"12.0.36"},{"ecosystem":"Maven","name":"org.eclipse.jetty.ee9:jetty-ee9-security","fixedVersion":"12.0.36"},{"ecosystem":"Maven","name":"org.eclipse.jetty:jetty-security","fixedVersion":"12.1.10"},{"ecosystem":"Maven","name":"org.eclipse.jetty.ee8:jetty-ee8-security","fixedVersion":"12.1.10"},{"ecosystem":"Maven","name":"org.eclipse.jetty.ee9:jetty-ee9-security","fixedVersion":"12.1.10"}],"fix":{"url":"https://github.com/jetty/jetty.project/pull/15160","label":"jetty/jetty.project#15160"},"references":[{"type":"WEB","url":"https://gitlab.eclipse.org/security/cve-assignment/-/work_items/120"},{"type":"ADVISORY","url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/10xxx/CVE-2026-10050.json"},{"type":"ADVISORY","url":"https://github.com/jetty/jetty.project/security/advisories/GHSA-2fvj-hgj9-j2gr"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-10050"},{"type":"WEB","url":"https://github.com/jetty/jetty.project/issues/15136"},{"type":"WEB","url":"https://github.com/jetty/jetty.project/pull/15160"},{"type":"WEB","url":"https://github.com/jetty/jetty.project/pull/15183"},{"type":"WEB","url":"https://github.com/jetty/jetty.project/commit/4bcdbc7db387ce9e20e2c7571a7250280466221d"},{"type":"WEB","url":"https://github.com/jetty/jetty.project/commit/d0bb829ccecbf19e3ad3d32f2649b2800f01222d"},{"type":"PACKAGE","url":"https://github.com/jetty/jetty.project"},{"type":"WEB","url":"https://github.com/jetty/jetty.project/releases/tag/jetty-12.0.36"},{"type":"WEB","url":"https://github.com/jetty/jetty.project/releases/tag/jetty-12.1.10"}],"provenance":{"sources":["OSV.dev","FIRST.org (EPSS)"],"lastVerified":"2026-10-24T10:30:47.924896376Z"}}