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

CVE-2026-59696: Erlang/OTP stdlib DOS Vulnerability

CVE-2026-59696 is a denial of service vulnerability in Erlang/OTP stdlib caused by improper validation of URI port components. Attackers can degrade availability using URIs with excessively long port digits. This article covers technical details, affected OTP versions, impact analysis, and mitigation strategies.

Published:

CVE-2026-59696 Overview

CVE-2026-59696 is a denial-of-service vulnerability in the Erlang/OTP stdliburi_string module. The flaw resides in uri_string:get_port/1, which passes a URI port substring to binary_to_integer/1 without any length bound. A remote attacker can supply a URI whose port component consists of up to roughly 1.26 million digits, forcing the calling process to spend hundreds of milliseconds on arbitrary-precision arithmetic. Because uri_string:parse/1 is the documented URI parsing interface, any application that parses attacker-supplied URIs is exposed without further configuration. The issue is classified under [CWE-1284] Improper Validation of Specified Quantity in Input.

Critical Impact

Remote unauthenticated attackers can degrade availability of Erlang/OTP services by supplying URIs with extremely long numeric port components, forcing costly big-integer conversions on every parse.

Affected Products

  • Erlang/OTP 21.0 through versions before OTP 27.3.4.17 (stdlib 3.5 through before 6.2.2.5)
  • Erlang/OTP 28.0 through versions before OTP 28.5.0.6 (stdlib 7.0 through before 7.3.0.2)
  • Erlang/OTP 29.0 through versions before OTP 29.0.6 (stdlib 8.0 through before 8.0.4)

Discovery Timeline

  • 2026-09-01 - CVE-2026-59696 published to NVD
  • 2026-09-01 - Last updated in NVD database

Technical Details for CVE-2026-59696

Vulnerability Analysis

The defect sits in the authority-parsing path of uri_string:parse/1 in Erlang/OTP stdlib. When the parser encounters the port component of a URI, uri_string:get_port/1 extracts the digit run and hands it to binary_to_integer/1. That conversion function accepts integers of any size by design, so bounding the input is the caller's responsibility. The port parser only catches error:badarg, which never fires for a syntactically valid digit string, no matter how long.

The conversion is reached from every authority-parsing branch, including host, registered-name, IPv4, and IPv6 forms. A single URI with roughly 1.26 million port digits costs the calling process hundreds of milliseconds of arbitrary-precision arithmetic. Attackers can repeat the request to consume scheduler time and degrade availability of the service.

Root Cause

The root cause is missing input length validation before invoking arbitrary-precision integer conversion. Erlang big-integer arithmetic scales with the digit count, so an unbounded numeric string translates directly into CPU cost. The port component of a legitimate URI is at most five digits, but uri_string:get_port/1 enforced no such bound.

Attack Vector

Exploitation requires only that an attacker-controlled URI reaches uri_string:parse/1. This includes HTTP clients and servers built on inets, LDAP clients using eldap, SNMP components, and any application layer that parses inbound URIs. No authentication or user interaction is required, and the attack is network-reachable.

erlang
% Patch: bound the port digit string before integer conversion
% Source: https://github.com/erlang/otp/commit/aba0fe8c2d700bf4ac94607cf7f00e53bbe4042d

-parse_port(Rest,Sport) ->
+parse_port(Rest,Sport) when length(Sport) =< 5 ->
     try	list_to_integer(Sport)
     catch _:_ -> parse_error(parsing_port,Rest)
-    end.
+    end;
+parse_port(Rest, _) ->
+    parse_error(parsing_port, Rest).

The fix adds a length guard of five characters, matching the maximum valid TCP/UDP port length, and returns a parse error for anything longer.

Detection Methods for CVE-2026-59696

Indicators of Compromise

  • Inbound HTTP requests, LDAP URIs, or other URI payloads containing port components with more than five digits.
  • Sudden spikes in scheduler run time or CPU utilization on Erlang beam processes handling URI parsing.
  • Repeated slow responses or timeouts correlated with requests carrying oversized numeric fields.

Detection Strategies

  • Inspect application logs for URIs where the host:port port field exceeds five characters, and treat such traffic as anomalous.
  • Instrument Erlang processes that call uri_string:parse/1 with reduction or wall-clock telemetry to surface abnormally expensive calls.
  • Deploy web application firewall or reverse proxy rules that reject request lines and header values containing URIs with excessive digit runs.

Monitoring Recommendations

  • Track per-request latency for endpoints that parse client-supplied URLs, LDAP URIs, or callback URLs, and alert on tail-latency regressions.
  • Correlate CPU pressure on Erlang nodes with request rate to identify low-volume, high-cost request patterns typical of algorithmic complexity attacks.
  • Monitor patch level of Erlang/OTP releases across the fleet and flag hosts still running versions before OTP 27.3.4.17, 28.5.0.6, or 29.0.6.

How to Mitigate CVE-2026-59696

Immediate Actions Required

  • Upgrade Erlang/OTP to 27.3.4.17, 28.5.0.6, or 29.0.6 or later, matching the deployed release branch.
  • Where immediate upgrade is not possible, place a proxy or WAF in front of exposed services to reject URIs whose port component exceeds five digits.
  • Audit application code for direct callers of uri_string:parse/1 or uri_string:get_port/1 that process untrusted input.

Patch Information

The fix is included in Erlang/OTP releases 27.3.4.17, 28.5.0.6, and 29.0.6, corresponding to stdlib 6.2.2.5, 7.3.0.2, and 8.0.4. The patches bound port digit length to five characters in uri_string, eldap, inets, and snmp. Details are in the GitHub Security Advisory GHSA-8qw4-2chm-mvj2 and the CNA advisory for CVE-2026-59696. See the reference commits aba0fe8c and e3be1cfe.

Workarounds

  • Wrap uri_string:parse/1 calls with an application-level length check that rejects URIs longer than expected, or that pre-validates the port substring.
  • Enforce a maximum request line and header size in fronting HTTP proxies to cap the digit run before it reaches Erlang.
  • For LDAP and SNMP integrations, restrict accepted URI sources to trusted endpoints until patches are deployed.
bash
# Example nginx rule: reject request URIs with port components longer than 5 digits
# Applied to any upstream Erlang/OTP service that parses forwarded URIs
location / {
    if ($request_uri ~ ":[0-9]{6,}") {
        return 400;
    }
    proxy_pass http://erlang_backend;
}

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.