Skip to main content
CVE Vulnerability Database
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:

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.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

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.