CVE-2026-59251
Executive Summary
CVE-2026-59251 is a denial-of-service vulnerability in Erlang/OTP's public_key application, specifically in the certificate policy tree implementation (pubkey_policy_tree) used during RFC 5280 path validation. A remote, unauthenticated attacker can exploit this flaw by presenting a crafted X.509 certificate chain during a TLS handshake, causing exponential growth of the policy tree (O(M^K) nodes for M policies per certificate across K certificates) that exhausts BEAM scheduler resources and system memory, crashing the entire Erlang VM. All OTP versions from 26.2 through 29.0.3 (including 27.3.4.x and 28.5.0.x branches) are affected, impacting any Erlang/Elixir application performing TLS client or mutual-TLS server operations. This is the same vulnerability class as the OpenSSL X509_verify_cert policy tree DoS (CVE-2022-0778).
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Technical Analysis
The vulnerability resides in lib/public_key/src/pubkey_policy_tree.erl, specifically in the add_leaves/2 and add_leaf_siblings/2 routines. During RFC 5280 certificate policy processing in public_key:pkix_path_validation/3, the certificate policy tree grows without an upper bound.
Vulnerability Mechanism:
The public_key library maintains a tree structure representing the policy relationships between certificates in a chain. When validating a certificate chain:
- Each certificate in the chain can assert one or more certificate policies (OIDs in the
certificatePoliciesextension). - The policy tree tracks how policies propagate from the trust anchor through intermediate certificates to the end entity.
- When two or more policies from one certificate must map to policies in the next certificate, the tree forks.
For each certificate i with P_i policies, the tree node count multiplies by P_i at each level. With a chain of K certificates each carrying M policies, the tree grows to O(M^K) nodes. The implementation uses recursive calls in add_leaves/2 and add_leaf_siblings/2 that do not check for a maximum depth or node count.
Attack Surface:
- Inbound TLS (mutual TLS servers): Any Erlang-based TLS server requiring client certificate authentication (
verify: verify_peerwithfail_if_no_peer_cert: true) presents a direct attack vector. The attacker sends a crafted client certificate chain during the TLS handshake. - Outbound TLS (clients): Any Erlang/Elixir HTTP client, database driver, or message queue consumer that validates the server's certificate chain is vulnerable to a malicious server presenting a crafted chain. This makes every TLS client a potential victim.
Key technical details:
- The attacker must control the certificate chain presented. This is the default trust model for TLS — no pre-authentication required beyond presenting the chain.
- The malicious chain must be cryptographically valid (or at least structurally valid enough to pass initial parsing) to reach the policy processing stage.
- The exponential blowup occurs during path validation, which runs on BEAM schedulers — CPU-bound exhaustion plus memory exhaustion on the node's heap.
- Memory exhaustion can trigger BEAM's memory allocation failure handling, crashing the VM.
Comparison to OpenSSL CVE-2022-0778: The same algorithmic complexity flaw exists in OpenSSL's X509_verify_cert, which was exploited in the wild. This confirms the practical exploitability of this vulnerability class.
Exploitation Scenarios
Attack Vector: Malicious TLS Server Targeting Erlang Clients
Reconnaissance: The attacker scans for services that use Erlang/Elixir TLS clients. Common targets include:
- Elixir/Phoenix applications using
:httpc,Finch,Mint, orReqfor outbound HTTPS calls - RabbitMQ clients with TLS verification enabled
- Ejabberd XMPP servers (both client and server connections)
- Erlang distribution over TLS (port 4369 with
-proto_dist inet_tls) - Cowboy-based HTTPS servers with mutual TLS
- Elixir/Phoenix applications using
Weaponization: The attacker generates a certificate chain where each certificate contains a large number of certificatePolicies extensions. The chain is constructed as follows:
- Generate a root CA certificate (self-signed or signed by a compromised/rogue CA).
- Generate K intermediate certificates (e.g., K=8), each asserting M policies (e.g., M=16). Each certificate's policies are unique OIDs to maximize branching.
- The final leaf certificate also carries a large policy set.
- Sign each certificate in the chain to ensure structural validity.
The attacker uses a tool like
opensslwith custom configurations or a scripting language (Python withcryptographylibrary) to programmatically create the chain.Triggering: The attacker sets up a malicious TLS server configured with this crafted chain. When an Erlang TLS client initiates a connection and requests the server certificate, the attacker's server presents the malicious chain.
Execution: The client's
public_key:pkix_path_validation/3proceeds with RFC 5280 policy processing. For each certificate in the chain,pubkey_policy_tree:add_leaves/2expands the tree. With 16 policies per certificate and 8 certificates, the tree grows to approximately 16^8 = 4.29 billion nodes. The client's BEAM VM exhausts CPU and memory within milliseconds, causing the scheduler to become unresponsive and eventually the VM to crash.Post-exploitation: The target application is completely unavailable. If running in a Kubernetes cluster, the pod may be killed and restarted, creating a crash-loop DoS. If the application uses Erlang distribution clustering, the node becomes isolated from the cluster, potentially taking down dependent services.
Alternative Scenario: Mutual TLS Server Exploitation
- An attacker with a valid-but-crafted client certificate chain connects to an Erlang TLS server configured with
verify: :verify_peer. - The crafted chain is presented during the client authentication phase.
- Same policy-tree explosion occurs on the server side, crashing the server.
Impact Assessment
CVSS Score: N/A — The vendor has not assigned a CVSS score. Based on the vulnerability characteristics (network-exploitable, no authentication, no user interaction, availability impact), an unofficial score would fall in the 7.5-8.6 (High) range. The lack of a formal CVSS score does not diminish the severity given the trivial exploitation vector and complete availability loss.
Business Impact:
- Complete service denial: The BEAM VM crash takes down the entire application — not just the TLS endpoint.
- Availability loss: A single small crafted certificate chain (< 10 KB) can crash a large VM instance.
- Collateral damage: Applications sharing the same Erlang node (e.g., one Phoenix app with multiple services) all go down simultaneously.
- Cluster disruption: Erlang distribution nodes lose connectivity, cascading failures.
Affected Systems:
- All OTP versions ≥ 26.2 and < 29.0.4
- Specifically: OTP 26.2 through 27.3.4.14, OTP 28.5.0 through 28.5.0.3, OTP 29.0.0 through 29.0.3
public_keyversions 1.15 through 1.21.3- Elixir applications built on affected OTP versions
- RabbitMQ (uses OTP), Ejabberd, WhatsApp's Erlang infrastructure, Discord's Elixir services, and other production Erlang deployments
Blast Radius:
- Any service accepting or initiating TLS connections with peer certificate validation
- High-traffic production systems are at greater risk because more connections mean more opportunitic exposure
- EPSS score of 0.00260 (17.7th percentile) suggests low active exploitation in the wild currently, but this is expected to rise once PoC code circulates
Detection Guidance
Sigma Rule
title: Erlang TLS Certificate Policy Tree DoS - Chain Policy Count Anomaly
id: 3f8b4c2a-9d51-4e72-8f3b-c9a4d5e6f7a1
status: experimental
description: Detects TLS certificate chains with excessive certificatePolicies extensions per certificate, indicating potential CVE-2026-59251 exploitation attempts.
author: Valtersit Threat Intelligence
date: 2026/06/15
logsource:
category: network_connection
product: tls
detection:
selection_tls_failures:
- event.category: tls
tls.version: ">=1.2"
tls.handshake_failure: true
- event.category: tls
tls.state: "failed"
selection_policy_count:
- tls.certificate_policy_count: ">=10"
- tls.cert_extensions_policies: ">=10"
selection_chain_length:
tls.certificate_chain_length: ">=4"
condition: selection_tls_failures and selection_policy_count and selection_chain_length
timeframe: 5m
level: high
tags:
- attack.t1498.001
- cve.2026.59251
- cwe.770
falsepositives:
- Legitimate complex PKI hierarchies with many policies (rare)
- Non-malicious misconfigured certificate chains
YARA Rule
rule CVE_2026_59251_Erlang_Policy_Tree_DoS {
meta:
author = "Valtersit Threat Intelligence"
date = "2026-06-15"
description = "Detects X.509 certificate chains with characteristics indicative of CVE-2026-59251 exploitation - many policy OIDs per certificate"
cve = "CVE-2026-59251"
severity = "high"
strings:
$policy_oid_1 = { 06 03 55 1D 20 } // Policy OID prefix (2.5.29.32)
$any_policy = { 06 05 2A 03 04 80 01 } // anyPolicy OID
$critical_policies = { 30 03 01 01 FF } // Critical flag true
condition:
// Trigger on certificate files or PCAPs containing many policy extension markers
#policy_oid_1 >= 10 and
filesize < 100MB
}
Suricata IDS Rule
alert tls any any -> any any (msg:"CVE-2026-59251 Erlang/OTP Certificate Policy Tree Denial of Service Attempt"; flow:to_client,established; tls.cert_chain_length:>4; tls.cert_policies:>10; tls.store; classtype:attempted-dos; sid:5925101; rev:1; metadata:created_at 2026_06_15, cve CVE_2026_59251, cwe 770;)
Elastic Detection
// Detect TLS handshake failures with abnormal certificate chain characteristics
sequence by source.ip with maxspan=5m
[network where event.category == "network" and network.protocol == "tls" and
event.action == "connection_attempt" and
tls.version != null]
[file where event.category == "file" and
file.extension == "crt" and
file.size < 100000 and
// Heuristic: policy extension markers in the certificate
(file.content contains "2.5.29.32" or file.content contains "CertificatePolicies")]
[network where event.category == "network" and network.protocol == "tls" and
event.outcome == "failure" and
event.reason contains "certificate" and
// Multiple failures from same source = scanning/exploitation pattern
sequence_num == 3]
Splunk SPL Query
index=netproxy sourcetype=tls* OR sourcetype=ssl*
| where like(cert_policies_count, "%>=10%") OR cert_policies_count > 10
| where cert_chain_length >= 4
| stats count by src_ip, dest_ip, cert_subject, cert_issuer
| where count > 5
| table _time, src_ip, dest_ip, cert_subject, cert_issuer, count
| rename src_ip as "Source IP", dest_ip as "Destination IP"
Wazuh OSSEC Rule
<group name="erlang_otp,">
<rule id="408227" level="12">
<decoded_as>tls</decoded_as>
<match>handshake failure|certificate verify failed|certificate error</match>
<regex>certificate_policies:\s*[0-9]{2,}|policy_count:\s*[0-9]{2,}</regex>
<description>CVE-2026-59251 potential exploitation - excessive certificate policies in TLS chain detected</description>
<mitre><id>T1498.001</id></mitre>
<group>attacker_technique,</group>
<info type="cve">CVE-2026-59251</info>
<id_suffix>59251</id_suffix>
</rule>
</group>
Mitigation & Patch Guidance
Patch Confidence: 2/4 (CLAIMED) — A single source (OSV) claims patches are available but this has not been independently confirmed by multiple sources at the time of writing.
1) Immediate Mitigations (no code changes required):
For outbound TLS connections: If your Erlang/Elixir application does not require PKI path validation, disable certificate policy processing. If using
:sslmodule directly, set:{verify, verify_none}However, this disables all certificate validation, which introduces MITM risks. Only use this as an emergency measure in isolated networks.
For inbound (server) connections: If you operate a mutual-TLS server, temporarily disable client certificate authentication (
verify_none) or restrict clients to a pre-vetted allowlist of certificates usingcacertfilewith exact-match validation only.Network-level mitigation: Deploy a WAF/reverse proxy that limits inbound connection rates and enforces maximum certificate size limits on the proxy layer (e.g., Nginx
ssl_client_certificatewithssl_verify_clienton the proxy).Resource limits: Run Erlang VMs under cgroups/container memory limits with
+MMmcs(maximum memory cache size) and+S(scheduler count) restrictions to contain the blast radius. SetERL_MAX_ETS_TABLESand memory limits via-env ERL_CRASH_DUMP_SECONDS.
2) Patch/Upgrade Steps:
- Fix immediately: Upgrade to:
- OTP 29.0.4 (latest stable)
- OTP 28.5.0.4 (if on the 28.x branch)
- OTP 27.3.4.15 (if on the 27.x branch)
- These versions include
public_key1.21.4, which addresses the unbounded policy tree growth. - For Elixir applications: verify your
elixirversion compatibility with the patched OTP before upgrading — usekiexorasdfto manage OTP versions. - For RabbitMQ: upgrade RabbitMQ to a version built on patched OTP (RabbitMQ 4.0.x+ with OTP 27.3.4.15+).
- For Docker deployments: update base images (
erlang:latest,erlang:27.3.4.15-slim, etc.) and rebuild.
3) Long-Term Hardening:
- Monitor upstream advisories: Track the OTP security mailing list and the erlang-otp GitHub repository for confirmed patch details, as patch confidence is only 2/4.
- Certificate chain validation limits: Implement application-level logic to reject chains containing more than a configurable number of certificates (e.g., max 5) or more than a configurable number of policies per certificate.
- Rate limiting: Implement connection-level rate limiting on all TLS endpoints to reduce the velocity of crafted-chain attacks.
- Redundancy: Deploy multiple Erlang nodes behind a load balancer so a single node crash does not cause full outage.
- Threat hunting: Regularly audit TLS handshake failure logs for patterns matching the Sigma/Suricata rules above.
References
- NVD Entry: https://nvd.nist.gov/vuln/detail/CVE-2026-59251
- Erlang/OTP Security Advisories: https://github.com/erlang/otp/security/advisories
- OSV Vulnerability Database: https://osv.dev/vulnerability/CVE-2026-59251
- Related OpenSSL Advisory (CVE-2022-0778): https://www.openssl.org/news/secadv/20220315.txt
- RFC 5280 (Internet X.509 PKI Certificate Policy Processing): https://www.rfc-editor.org/rfc/rfc5280
Threat Actor Campaigns: As of this report (June 2026), no active threat actor campaigns exploiting CVE-2026-59251 have been publicly documented. The EPSS score of 0.00260 ranks this vulnerability at the 17.7th percentile of exploited CVEs, indicating no known in-the-wild exploitation has been confirmed in major datasets. However, given the OpenSSL predecessor (CVE-2022-0778) was exploited within weeks of disclosure, organizations running affected Erlang/OTP versions should assume exploitation risk will materialize once PoC code circulates in underground forums.
What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.