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

CVE-2026-69664: Erlang/OTP inets httpd DOS Vulnerability

CVE-2026-69664 is a denial of service flaw in Erlang/OTP inets httpd that allows attackers to exhaust worker connections through malformed chunked requests. This post explains its impact, affected versions, and mitigation steps.

Published:

CVE-2026-69664 Overview

CVE-2026-69664 is a denial-of-service vulnerability in the Erlang/OTP inetshttpd HTTP server. An unauthenticated remote attacker can exhaust the server's worker pool by sending requests with a chunked body whose chunk-size line is not a valid hexadecimal number. Each malformed request permanently occupies a worker process because no timeout reclaims the connection. Repeating the request across connections denies service to legitimate clients. The default configuration is affected, as the periodic byte-rate check requires minimum_bytes_per_second to be set. The flaw is classified as Missing Release of Resource after Effective Lifetime [CWE-772].

Critical Impact

Unauthenticated remote attackers can render inetshttpd servers unavailable to legitimate clients by exhausting the worker pool with a small volume of malformed chunked requests.

Affected Products

  • Erlang/OTP from OTP 18.1.4 before OTP 27.3.4.17 (inets from 6.0.3 before 9.3.2.7)
  • Erlang/OTP from OTP 28.0 before OTP 28.5.0.6 (inets from 9.4 before 9.6.2.3)
  • Erlang/OTP from OTP 29.0 before OTP 29.0.6 (inets from 9.7 before 9.7.2)

Discovery Timeline

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

Technical Details for CVE-2026-69664

Vulnerability Analysis

The vulnerability resides in how httpd_request_handler resumes chunked-body decoding when the chunk-size line arrives in a separate write from the headers. When the body arrives with the headers, httpd_request_handler:handle_body/3 invokes http_chunk:decode/3 inside a try ... catch throw:Error block. The {error, {chunk_size, _}} thrown by http_chunk:decode_size/4 is correctly translated into a 400 Bad Request response.

When the chunk size arrives later, the decoder is resumed through a bare catch in httpd_request_handler:handle_info/2. The bare catch converts the thrown error into a return value rather than propagating it. The resulting error tuple is then treated as the next decoder continuation. The socket is re-armed and the worker waits indefinitely for data that never comes.

Root Cause

The request timeout is cancelled once headers are accepted, and the periodic byte-rate check is only armed when minimum_bytes_per_second is configured. Because neither safeguard is active by default, the stuck worker is never reclaimed. Repeating the malformed request across connections consumes every worker in the pool.

Attack Vector

An unauthenticated remote attacker sends an HTTP request with Transfer-Encoding: chunked, delivers valid headers first, then in a subsequent write sends a chunk-size line containing non-hexadecimal characters. Each request permanently occupies one worker.

text
// Patch excerpt: lib/inets/src/http_server/httpd_request_handler.erl
 	 (Proto =:= ssl) orelse 
 	 (Proto =:= dummy)) andalso is_binary(Data)) ->
 
-    PROCESSED = (catch Module:Function([Data | Args])),
     NewDataSize = case State#state.byte_limit of
 		      undefined ->
 			  undefined;
 		      _ ->
 			  State#state.data + byte_size(Data)
 		  end,
 
-    case PROCESSED of       
+    try Module:Function([Data | Args]) of
         {ok, Result} ->
 	    NewState = case NewDataSize of
 			   undefined ->

The fix replaces the bare catch with a try ... of construct so that thrown errors from the chunk decoder propagate correctly and terminate the worker. Source: GitHub Commit a3adf6307843.

Detection Methods for CVE-2026-69664

Indicators of Compromise

  • HTTP requests using Transfer-Encoding: chunked where the chunk-size line contains non-hexadecimal characters.
  • Chunked request bodies split across multiple TCP writes, with headers in the first write and the malformed chunk-size arriving later.
  • Sustained growth in the number of active httpd_request_handler worker processes without a corresponding rise in completed requests.
  • Client-visible symptoms such as connection acceptance without HTTP response, followed by service unavailability.

Detection Strategies

  • Inspect HTTP traffic at a reverse proxy or WAF for chunked requests whose chunk-size field does not match the regex ^[0-9A-Fa-f]+(;.*)?$.
  • Instrument inets deployments to log the count of live handler processes and alert when the count approaches the configured worker limit.
  • Correlate TCP connections that remain open past the expected keep_alive_timeout without producing a response.

Monitoring Recommendations

  • Track worker-pool saturation metrics for any process exposing inetshttpd on the network.
  • Enable structured access logging and alert on requests that never complete a response cycle.
  • Monitor upstream reverse proxies for 504 or connection-timeout patterns targeting Erlang-backed services.

How to Mitigate CVE-2026-69664

Immediate Actions Required

  • Upgrade Erlang/OTP to 27.3.4.17, 28.5.0.6, or 29.0.6 (or later within the respective branch) as soon as feasible.
  • If patching is not immediately possible, place inetshttpd behind a reverse proxy that validates chunked encoding and terminates malformed requests.
  • Configure minimum_bytes_per_second in the httpd configuration so the periodic byte-rate check can reclaim stalled workers.

Patch Information

The fix replaces the bare catch around the decoder invocation with a try ... of block in lib/inets/src/http_server/httpd_request_handler.erl, ensuring thrown chunk-size errors propagate and the worker terminates. See the GitHub Security Advisory GHSA-mr35-8h7w-w3gq and the corresponding commits a3adf6307843, bd4e74348c6b, and df1a9ca4666e for the full patch set. Additional context is available in the CNA advisory and the OSV entry EEF-CVE-2026-69664.

Workarounds

  • Set minimum_bytes_per_second in the httpd service configuration so idle workers are terminated when data flow stalls.
  • Front the service with a hardened reverse proxy (for example, nginx or HAProxy) that reassembles and validates chunked bodies before forwarding.
  • Restrict network exposure of inetshttpd to trusted clients until the patched OTP release is deployed.
bash
# Configuration example: enforce a minimum byte rate in httpd
# httpd.conf (Erlang term format)
[{server_name, "example"},
 {port, 8080},
 {server_root, "/var/inets"},
 {document_root, "/var/inets/htdocs"},
 {minimum_bytes_per_second, 64}].

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

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.