CVE-2026-89422: 
CBL Mariner vulnerability analysis and mitigation

Overview

CVE-2026-89422 is a Key Exchange without Entity Authentication vulnerability (CWE-322) in the Erlang/OTP ssl application that allows an unauthenticated network attacker to impersonate any TLS 1.3 server to an affected client. By sending an unsolicited pre_shared_key extension in the ServerHello, the attacker causes the client to complete the TLS 1.3 handshake without validating the server's certificate, bypassing all authentication checks. Affected versions span OTP 22.2 through OTP 27.3.4.17, 28.x before 28.5.0.7, and 29.x before 29.1.1 (ssl library versions 9.5 through 11.2.12.12, 11.6.0.5, and 11.7.6). The vulnerability was disclosed on September 22, 2026, and carries a CVSS v4.0 base score of 9.3 (Critical) (GitHub Advisory, Feedly).

Technical details

The root cause lies in two flawed functions in the Erlang/OTP TLS 1.3 client state machine. First, tls_gen_connection_1_3:handle_resumption/2 sets resumption = true solely on the presence of a pre_shared_key extension in the ServerHello, without verifying that the client ever offered a PSK. Second, tls_handshake_1_3:get_pre_shared_key/4 silently fell back to an all-zero "no PSK" value when no matching ticket was found, rather than aborting. The combination causes maybe_resumption/1 to route the client state machine directly to wait_finished, skipping the wait_cert_cr, wait_cert, and wait_cv states entirely — meaning certificate path validation, verify_fun, hostname verification, partial chain processing, CRL checking, and OCSP stapling are all bypassed. The attacker only needs to complete an ECDHE key exchange with their own ephemeral key; no certificate, private key, or prior session is required. The vulnerability was introduced in commit 21b8a1b (OTP 22.2) and is exploitable against the default client configuration whenever TLS 1.3 is negotiated (GitHub Advisory, Fix Commit).

Impact

Successful exploitation results in a complete server authentication bypass: the attacker holds all TLS traffic keys and can read everything the application sends (credentials, tokens, session cookies, request bodies) and forge every server response. This affects any Erlang/OTP consumer of ssl:connect when TLS 1.3 is negotiated, including httpc over HTTPS, database and messaging client libraries, and TLS distribution clients. The only application-visible anomaly on a compromised connection is that ssl:peercert/1 returns {error, no_peercert} despite verify_peer being configured, and ssl:connection_information/2 reports {session_resumption, true} for a client that never held a ticket. Confidentiality and integrity of all data in transit are fully compromised; availability is not directly impacted (GitHub Advisory).

Exploitability

No public proof-of-concept exploit code has been observed, and there is no evidence of in-the-wild exploitation at the time of disclosure (Feedly). However, the attack is fully automatable (NVD SSVC: automatable=yes) and requires no privileges, no user interaction, and no prior session — only the ability to answer a TLS 1.3 connection (either as a malicious host or as an on-path attacker). The EPSS score is approximately 0.37%, reflecting low current exploitation probability. The vulnerability is not listed in the CISA KEV catalog. The vulnerability was credited to Milad Nasr and Luna Tong at Anthropic, who reported it responsibly to the Erlang/OTP project (GitHub Advisory).

Exploitation steps

  1. Reconnaissance: Identify applications using Erlang/OTP ssl versions 9.5–11.2.12.12, 11.6.0.5, or 11.7.6 that make outbound TLS 1.3 connections (e.g., services using httpc, RabbitMQ clients, database drivers built on OTP). Position as either the intended server (DNS/BGP hijack, rogue endpoint) or an on-path attacker able to intercept the TCP connection.
  2. Accept the TCP connection: Listen on the target port and accept the client's TCP connection before or instead of the legitimate server.
  3. Receive ClientHello: Read the client's TLS 1.3 ClientHello to extract the client's legacy_session_id (required to be echoed) and the client's x25519 key_share.
  4. Craft malicious ServerHello: Construct a ServerHello that includes: (a) the echoed legacy_session_id, (b) a valid supported_versions extension indicating TLS 1.3, (c) a key_share extension with the attacker's own ephemeral x25519 public key, and (d) a pre_shared_key extension with selected_identity = 0 — an extension the client never offered.
  5. Compute handshake keys: Derive the ECDHE shared secret using the client's x25519 public key and the attacker's private key. Compute the RFC 8446 §7.1 handshake traffic secrets using the standard (non-PSK) key schedule.
  6. Send encrypted flight: Transmit the ServerHello, a ChangeCipherSpec record, and an encrypted record containing EncryptedExtensions and a Finished message computed from the attacker's own handshake transcript. No Certificate or CertificateVerify messages are sent.
  7. Handshake completes: The vulnerable client, upon receiving the unsolicited pre_shared_key extension, sets resumption=true and routes directly to wait_finished, skipping all certificate validation states. ssl:connect returns {ok, Socket} to the application.
  8. Intercept traffic: The attacker now holds all application-layer traffic keys and can read plaintext data sent by the client (credentials, tokens, etc.) and inject forged responses (GitHub Advisory, Fix Commit).

Indicators of compromise

  • Application Logs: ssl:peercert/1 returning {error, no_peercert} on connections configured with {verify, verify_peer} — this should never occur on a legitimate connection.
  • Application Logs: ssl:connection_information/2 reporting {session_resumption, true} for a client that has no prior session tickets (e.g., on first connection to a host, or with session_tickets = disabled).
  • Network: TLS 1.3 ServerHello messages containing a pre_shared_key extension (type 0x0029 / decimal 41) in contexts where the corresponding ClientHello contained no pre_shared_key extension — detectable via deep packet inspection or TLS-aware network monitoring.
  • Network: Absence of Certificate and CertificateVerify handshake messages in a TLS 1.3 full handshake flow (i.e., a handshake that proceeds directly from EncryptedExtensions to Finished without certificate records).
  • Process/Runtime: Erlang crash reports or alert logs containing {tls_alert, {illegal_parameter, _}} with reason {unsolicited_pre_shared_key, _} on patched systems — indicating an active exploitation attempt was blocked (GitHub Advisory).

Mitigation and workarounds

Upgrade Erlang/OTP to one of the patched versions: OTP 27.3.4.18, OTP 28.5.0.7, or OTP 29.1.1 (corresponding to ssl library versions 11.2.12.13, 11.6.0.6, and 11.7.7 respectively). The fix modifies get_pre_shared_key/4 to abort with a fatal illegal_parameter alert (reason {unsolicited_pre_shared_key, _}) instead of silently falling back to the zero PSK, and relocates the handle_resumption/2 call to after PSK validation so the resumption flag can never be set for an unsolicited PSK. As an immediate workaround for systems that cannot be patched promptly, restrict TLS clients to TLS 1.2 by setting {versions, ['tlsv1.2']} in ssl options — this avoids the vulnerable code path entirely, at the cost of losing TLS 1.3. There is no configuration that preserves TLS 1.3 while mitigating the vulnerability on unpatched versions (GitHub Advisory, Fix Commit).

Community reactions

The vulnerability was discovered and responsibly disclosed by Milad Nasr and Luna Tong at Anthropic, with the fix authored by Ingela Andín of the Erlang/OTP core team (GitHub Advisory). The Canadian Centre for Cyber Security issued a security advisory (AV26-948) covering the Erlang vulnerability (CCCS Advisory). Coverage appeared on security news aggregators including Malware News and Undercode News, with the latter highlighting the severity of the server impersonation capability. Social media discussion on Mastodon noted the critical nature of the bypass, particularly its impact on the default verify_peer configuration used by most production deployments.

Additional resources

Linux Distribution fix status

Fix availability across major Linux distributions and their releases.

Debian

Fixed

bookworm

erlang

Affected

sid

erlang: 1:29.1.1+dfsg-1

Fixed

trixie

erlang

Affected

Ubuntu

Fixed

bionic (esm-infra)

erlang

Not Affected

devel

erlang

Affected

focal (esm-infra)

erlang: 1:22.2.7+dfsg-1ubuntu0.5+esm3

Fixed

jammy

erlang: 1:24.2.1+dfsg-1ubuntu0.8

Fixed

noble

erlang: 1:25.3.2.8+dfsg-1ubuntu4.8

Fixed

resolute

erlang: 1:27.3.4.6+dfsg-1ubuntu0.2

Fixed

trusty (esm-infra-legacy)

erlang

Not Affected

xenial (esm-infra-legacy)

erlang

Not Affected

Source: This report was generated using AI

Related CBL Mariner vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

CVE-2026-98383HIGH7.1
  • Linux Kernel logoLinux Kernel
  • kernel-64k-modules-internal
NoYesOct 09, 2026
CVE-2026-98381HIGH7.1
  • Linux Kernel logoLinux Kernel
  • kernel-zfcpdump-modules-partner
NoYesOct 09, 2026
CVE-2026-98382MEDIUM5.1
  • Linux Kernel logoLinux Kernel
  • kernel-64k-debug
NoYesOct 09, 2026
CVE-2026-98380MEDIUM5.1
  • Linux Kernel logoLinux Kernel
  • linux-nvidia-tegra
NoYesOct 09, 2026
CVE-2026-98384LOW3.3
  • Linux Kernel logoLinux Kernel
  • linux-drivers-sound
NoYesOct 09, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Additional Wiz resources

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management