Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2024-32650

CVE-2024-32650: Rustls Denial of Service Vulnerability

CVE-2024-32650 is a denial of service flaw in Rustls that causes infinite loops when processing malicious network input. This article covers the technical details, affected versions, impact, and mitigation.

Published:

CVE-2024-32650 Overview

CVE-2024-32650 is an infinite loop vulnerability [CWE-835] in Rustls, a modern Transport Layer Security (TLS) library written in Rust. The flaw resides in the rustls::ConnectionCommon::complete_io method used by blocking server implementations. A remote, unauthenticated client can trigger the condition by sending a close_notify alert immediately after the client_hello message. The server then enters an infinite loop inside complete_io, consuming CPU resources and stalling the connection thread. Maintainers fixed the issue in Rustls versions 0.23.5, 0.22.4, and 0.21.11.

Critical Impact

Remote attackers can lock blocking Rustls server threads into an infinite loop with a single malformed handshake sequence, producing a denial of service against TLS endpoints.

Affected Products

  • Rustls versions prior to 0.21.11 in the 0.21.x branch
  • Rustls versions prior to 0.22.4 in the 0.22.x branch
  • Rustls versions prior to 0.23.5 in the 0.23.x branch

Discovery Timeline

  • 2024-04-19 - CVE-2024-32650 published to the National Vulnerability Database (NVD)
  • 2026-04-15 - Last updated in NVD database

Technical Details for CVE-2024-32650

Vulnerability Analysis

The defect is an unbounded loop [CWE-835] inside the connection state machine of Rustls. The complete_io helper drives blocking I/O by repeatedly calling wants_write and wants_read until the handshake completes. When a client transmits a close_notify alert immediately after client_hello, the connection reaches a state where neither read nor write progress is possible, yet is_handshaking continues to return true. The loop never exits.

Because the attack requires only a single TLS record after the initial hello, exploitation is cheap and repeatable. A small number of clients can saturate available worker threads in any service that depends on blocking Rustls connections. EPSS data places the exploitation probability at approximately 0.95%.

Root Cause

Two defects combined to produce the loop. First, complete_io had no guard for the case where the connection wanted neither additional reads nor writes during the handshake. Second, common_state accepted close_notify alerts before the peer was authenticated, marking the connection as having received an end-of-file while still in the handshake state. The state machine then entered a permanent stall.

Attack Vector

Any attacker who can reach a TCP listener served by a vulnerable blocking Rustls server can trigger the condition. The exploit does not require authentication, valid certificates, or any prior session state. The client opens a TCP connection, transmits a standard client_hello, and immediately follows with a TLS alert record carrying close_notify.

rust
         loop {
             let until_handshaked = self.is_handshaking();
 
+            if !self.wants_write() && !self.wants_read() {
+                // We will make no further progress.
+                return Ok((rdlen, wrlen));
+            }
+
             while self.wants_write() {
                 wrlen += self.write_tls(io)?;
             }

Source: rustls commit 6e938bcfe8 - complete_io: bail out if progress is impossible. The patch adds an explicit termination condition so complete_io returns when no further I/O progress is possible.

rust
         }
 
         // If we get a CloseNotify, make a note to declare EOF to our
-        // caller.
-        if alert.description == AlertDescription::CloseNotify {
+        // caller.  But do not treat unauthenticated alerts like this.
+        if self.may_receive_application_data && alert.description == AlertDescription::CloseNotify {
             self.has_received_close_notify = true;
             return Ok(());
         }

Source: rustls commit f45664fbded - Don't specially handle unauthenticated close_notify alerts. The patch ignores close_notify alerts received before the connection is authorized to carry application data.

Detection Methods for CVE-2024-32650

Indicators of Compromise

  • TLS handshakes where a client transmits a close_notify alert record immediately following client_hello without completing key exchange.
  • Sustained 100% CPU utilization on a single worker thread that is bound to an established TCP connection but produces no application-layer traffic.
  • Growing counts of long-lived half-open TLS sessions terminating in the handshake phase from the same source IP range.

Detection Strategies

  • Inspect server process metrics for threads stuck in a tight loop while owning a TLS socket; correlate with the Rustls version reported by the binary.
  • Use packet capture or eBPF probes to flag clients that send TLS alert records before completing the handshake.
  • Audit the dependency tree of Rust services with cargo tree | grep rustls and flag versions below 0.21.11, 0.22.4, or 0.23.5.

Monitoring Recommendations

  • Track per-connection CPU time and elapsed handshake duration; alert on TLS sessions that exceed expected handshake latency by an order of magnitude.
  • Monitor for an unusual ratio of close_notify alerts to completed handshakes at the load balancer or TLS terminator.
  • Watch for thread pool exhaustion or queue saturation on services that wrap Rustls in blocking I/O loops.

How to Mitigate CVE-2024-32650

Immediate Actions Required

  • Upgrade Rustls to 0.21.11, 0.22.4, or 0.23.5 or later depending on the branch in use.
  • Rebuild and redeploy all Rust binaries and container images that statically link Rustls, including downstream crates such as hyper-rustls, tokio-rustls, and reqwest.
  • Restart long-running services after deployment to release any worker threads already trapped in the loop.

Patch Information

The fix is delivered across three commits in the rustls/rustls repository. Commit 6e938bcfe8 adds the progress guard to complete_io. Commit f45664fbded refuses to honor close_notify alerts before the handshake authorizes application data. Commit 2123576840 backports the changes. Full disclosure details are in GitHub Security Advisory GHSA-6g7w-8wpp-frhj.

Workarounds

  • Where upgrade is not immediately possible, switch the service to a non-blocking async runtime such as tokio-rustls, which does not invoke complete_io in the affected pattern.
  • Place a TLS-aware reverse proxy or load balancer in front of the Rustls server to terminate TLS upstream and absorb malformed handshake traffic.
  • Apply per-connection handshake timeouts at the network or application layer to forcibly close sockets that fail to complete the handshake within a fixed window.
bash
# Verify the resolved Rustls version in a Cargo workspace
cargo update -p rustls
cargo tree --invert rustls | head -n 40

# Confirm a fixed version is in use
cargo tree | grep -E 'rustls v(0\.21\.(1[1-9]|[2-9][0-9])|0\.22\.[4-9]|0\.23\.[5-9])'

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.