Skip to main content
Vulnerability Database/CVE-2026-59251

CVE-2026-59251: Erlang/OTP public_key DoS Vulnerability

CVE-2026-59251 is a denial of service vulnerability in Erlang/OTP public_key that allows attackers to exhaust memory via crafted X.509 certificate chains. This article covers technical details, affected versions, and mitigation.

Published:

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Sources: National Vulnerability Database, CISA KEV, Exploit-DB

CVE-2026-59251 Overview

CVE-2026-59251 is a denial of service vulnerability in Erlang/OTP's public_key application affecting RFC 5280 certificate path validation. A remote unauthenticated attacker can crash the BEAM virtual machine by presenting a crafted X.509 certificate chain during the TLS handshake. The certificate policy tree maintained by pubkey_policy_tree grows without bounds, exhausting memory and pinning schedulers. The flaw impacts any TLS client validating a peer chain and any mutual-TLS server accepting client certificates. The vulnerability class is identical to OpenSSL's X509_verify_cert policy tree DoS. It is categorized under [CWE-770] (Allocation of Resources Without Limits).

Critical Impact

Any TLS endpoint that validates peer certificate chains can be crashed by a single crafted handshake, taking down the entire Erlang VM and every service it hosts.

Affected Products

  • Erlang/OTP 26.2 through versions before OTP 29.0.4
  • Erlang/OTP 28.5.0.4 (fixed release on the 28.x branch)
  • Erlang/OTP 27.3.4.15 (fixed release on the 27.x branch), corresponding to public_key from 1.15 before 1.21.4, 1.20.3.4, and 1.17.1.5

Discovery Timeline

  • 2026-07-27 - CVE-2026-59251 published to NVD
  • 2026-07-30 - Last updated in NVD database

Technical Details for CVE-2026-59251

Vulnerability Analysis

The defect lives in public_key:pkix_path_validation/3, the function that walks an X.509 chain and applies RFC 5280 policy processing. During policy processing, pubkey_policy_tree maintains a tree of certificate policies extracted from each certificate in the chain. The helper routines pubkey_policy_tree:add_leaves/2 and pubkey_policy_tree:add_leaf_siblings/2 extend the tree by one node per policy per certificate. No cap exists on the total number of nodes.

When a chain of K certificates each declares M distinct policies, the tree grows on the order of M^K nodes. A modest chain with many policies per certificate is enough to pin BEAM schedulers and exhaust node memory. Because the work is performed inside a native validation path, the schedulers do not yield, and the entire VM becomes unresponsive before it crashes.

Root Cause

The root cause is missing input validation on attacker-controlled certificate content combined with unbounded resource allocation during policy tree construction. The affected files are lib/public_key/src/pubkey_policy_tree.erl and its exported helpers. The upstream fix introduces a monotonic policy_tree_node_count counter into the path_validation_state record and refactors add_leaves and add_leaf_siblings to accept the counter, aborting validation with a new policy_tree_exceeded error when the cap is reached.

Attack Vector

Exploitation requires only the ability to present a certificate chain to the victim. This is the normal precondition for any TLS handshake. A malicious TLS server can crash any Erlang client that validates the server chain (the SSL/TLS default). A malicious client can crash any Erlang server configured for mutual TLS. No authentication, user interaction, or prior access is required.

text
-record(path_validation_state,
        {
         valid_policy_tree,
+        %% Monotonic count of nodes ever added to policy tree (never decremented by pruning).
+        policy_tree_node_count = 1 :: non_neg_integer(),
         user_initial_policy_set,
         explicit_policy,
         inhibit_any_policy,

Source: Erlang/OTP commit f04c6bba — the patch caps policy tree growth by tracking node counts in the validation state.

text
-export([add_leaves/2,
-        add_leaf_siblings/2,
+-export([add_leaves/3,
+        add_leaf_siblings/3,
         any_leaves/1,
         all_leaves/1,
         collect_qualifiers/2,

Source: Erlang/OTP commit f8580fc1 — the exported helpers now accept the running node count and return policy_tree_exceeded when the bound is exceeded.

Detection Methods for CVE-2026-59251

Indicators of Compromise

  • Sudden BEAM VM crashes or oom-killer events on Erlang nodes handling TLS traffic
  • Sustained scheduler saturation on a single node coinciding with an inbound or outbound TLS handshake
  • TLS peer certificates that declare unusually large sets of certificate policy OIDs across multiple chain elements
  • Repeated failed handshakes from the same remote peer preceding an availability outage

Detection Strategies

  • Inspect captured TLS handshakes for certificate chains with an abnormal count of certificatePolicies extension entries per certificate
  • Alert on Erlang crash dumps that reference pubkey_policy_tree, add_leaves, or add_leaf_siblings on the stack
  • Correlate BEAM memory spikes with ssl application activity to identify handshakes that consume disproportionate memory

Monitoring Recommendations

  • Track BEAM process memory, scheduler utilization, and reduction counts on all TLS-facing Erlang services
  • Log the version of public_key and OTP in use on each node and flag hosts running versions before the fixed releases
  • Enable TLS handshake failure logging at the application layer and forward events to a central SIEM for correlation across nodes

How to Mitigate CVE-2026-59251

Immediate Actions Required

  • Upgrade Erlang/OTP to 29.0.4, 28.5.0.4, or 27.3.4.15, whichever matches the currently deployed release branch
  • If upgrade is blocked, restrict which peers are allowed to complete a TLS handshake using network ACLs or a validating proxy
  • Audit all Erlang services that terminate or initiate TLS, including internal service-to-service traffic and outbound API clients

Patch Information

The Erlang Ecosystem Foundation released fixed builds in OTP 29.0.4, OTP 28.5.0.4, and OTP 27.3.4.15, corresponding to public_key versions 1.21.4, 1.20.3.4, and 1.17.1.5. Details are documented in the GitHub Security Advisory GHSA-622p-qfh6-c352, the CNA advisory at cna.erlef.org, and the OSV record EEF-CVE-2026-59251. Version ordering rules are described in the Erlang versions documentation.

Workarounds

  • Terminate TLS at an unaffected reverse proxy (for example, a hardened NGINX or HAProxy instance) so that certificate path validation is not performed by the vulnerable Erlang node
  • For mutual TLS deployments, constrain the accepted client certificate issuers to a private CA that does not emit certificates containing large policy sets
  • Restrict outbound TLS destinations from Erlang services to an allowlist, reducing exposure to hostile server certificates
bash
# Verify the installed OTP and public_key versions on each node
erl -noshell -eval 'io:format("OTP: ~s~npublic_key: ~s~n", [erlang:system_info(otp_release), begin {ok, V} = application:get_key(public_key, vsn), V end]), halt().'

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Sources: National Vulnerability Database, CISA KEV, Exploit-DB

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.