A freshly disclosed flaw in the Rustls TLS library lets any remote attacker lock up a server with nothing more than a well-timed “close” message during the handshake, consuming CPU resources until the process is restarted. Microsoft’s security advisory (CVE-2024-32650) rates the denial-of-service impact as “total loss of availability,” meaning a single unauthenticated connection can prevent the service from handling legitimate traffic. The Rustls maintainers have shipped fixes across three release lines, but every admin running a Rustls-based service—especially those exposed to the internet—must update or deploy mitigations immediately.

What Happened with the Rustls Handshake Flaw

The vulnerability sits in rustls::conn::ConnectionCommon::completeio(), the core I/O completion loop that drives TLS handshakes when Rustls operates in blocking mode. Under normal conditions, this function pushes the handshake through its stages, returning when progress is made or an error occurs. The problem arises when a client sends a closenotify alert immediately after the initial ClientHello message. In affected versions, that sequence causes the loop to spin endlessly, never making progress and never yielding an error.

The result is classic CPU exhaustion: one or more threads peg at 100% utilization, the server stops accepting new connections, and existing sessions may hang. Because the trigger is a valid—though unusual—TLS protocol sequence, network-level intrusion detection systems that don’t perform deep packet inspection are unlikely to flag the attack. An attacker needs no credentials and no encryption keys; just the ability to open a TCP connection and send the two messages in order.

Rustls maintainers have confirmed the bug and released patches for all supported release branches:

  • 0.23.x: fixed in version 0.23.5 and later
  • 0.22.x: fixed in version 0.22.4 and later
  • 0.21.x: fixed in version 0.21.11 and later

Any server linking against an older version of these lines is vulnerable if it uses the blocking server API. The fix adjusts the handshake state machine so that receiving an early closenotify correctly terminates the connection rather than looping.

Who Is Affected—and What’s at Stake

This isn’t a theoretical edge case. Rustls has gained traction in everything from API gateways to embedded devices precisely because it avoids the memory-safety pitfalls of C-based TLS stacks. Its blocking API is widely used in synchronous applications, thread-per-connection servers, and anywhere developers opt for simplicity over async event loops.

If you run any of the following, you need to check your Rustls version:

  • Web servers, reverse proxies, or load balancers built in Rust
  • Network appliances or IoT gateways that terminate TLS with Rustls
  • Containerized microservices that accept TLS connections directly
  • Development or CI systems that spin up test servers with Rustls

The attack surface is broad because the bug can be triggered remotely over any standard TLS port. An attacker can amplify the damage by sending a handful of crafted handshakes to a multithreaded server, quickly exhausting all available worker threads. From the outside, the service becomes completely unresponsive—new connections hang or time out, health checks fail, and dependent systems cascade into failure.

Importantly, the vulnerability does not compromise confidentiality or integrity. There’s no data leak and no opportunity for code execution. But for any online business, losing availability can be just as damaging as a breach. The Microsoft advisory describes the impact as “total loss of availability, resulting in the attacker being able to fully deny access to resources,” confirming that this is a drop-everything-and-fix situation.

How We Got Here: Rustls’ Design and This State Machine Bug

Rustls was built as a safer alternative to OpenSSL and other TLS libraries, leveraging Rust’s memory safety guarantees to eliminate entire categories of bugs. Its adoption accelerated as organizations sought to reduce the risk of memory corruption vulnerabilities like Heartbleed. However, the library’s focus on memory safety didn’t immunize it against logic errors in its protocol state machine—the series of allowed states and transitions during a TLS handshake.

The handshake is a complex dance of messages: ClientHello, ServerHello, certificate exchange, key agreement, and finished messages. The protocol also includes an Alert message type, with closenotify used to gracefully shut down a connection. Sending a closenotify before the handshake completes is permitted by the TLS specification, but it’s rarely seen in practice. Rustls’ blocking I/O loop didn’t handle this edge case correctly; instead of recognizing the alert as a terminal signal and closing the connection, it kept trying to read more data, looping indefinitely.

This class of bug—a missing or incorrect state transition—is notoriously hard to catch through regular unit testing. It often requires fuzzing unusual message sequences or stress-testing with malformed inputs. The Rustls team acted quickly once the issue was reported, publishing fixes within days, but the vulnerability had been present for several releases across multiple branches.

Immediate Actions: Patch, Mitigate, or Offload

The definitive fix is to update to a patched Rustls version. But in large deployments, that can take time. Here’s a prioritized action plan:

1. Apply the Patch (Permanent Fix)

For Rust projects, update your Cargo.toml dependency and rebuild:

# For 0.23.x users
cargo update -p rustls --precise 0.23.5
cargo build --release

For 0.22.x users

cargo update -p rustls --precise 0.22.4 cargo build --release

For 0.21.x users

cargo update -p rustls --precise 0.21.11 cargo build --release

If you use a wrapper crate like tokio-rustls, check its dependency chain; you may need to update it to a version that pulls in the patched Rustls. Run cargo tree -p rustls to see every crate that depends on Rustls and verify they all point to a fixed version.

For systems that install Rustls via OS packages (e.g., librustls-dev on Linux distributions), wait for vendor updates and apply them promptly. Check your distribution’s security advisory page for CVE-2024-32650.

2. While You Wait: Short-Term Mitigations

If you can’t patch immediately, reduce your exposure with these steps:

  • Move TLS termination to a patched proxy: Place a reverse proxy (NGINX, HAProxy, or cloud load balancer) in front of the vulnerable server and let it handle TLS handshakes. Ensure the proxy uses a TLS library that isn’t based on affected Rustls versions.
  • Enable strict connection rate limiting: Use iptables, fail2ban, or cloud firewall features to cap the number of new TLS connections per source IP per minute. This won’t stop a distributed attack but can buy time.
  • Set aggressive handshake timeouts: If your application framework allows it, configure a short timeout for the TLS handshake phase (e.g., 5 seconds). This will kill hanging connections faster, though the CPU may still spin during that window.
  • Switch to async if possible: If your application can use Rustls’ async acceptor (e.g., with tokio-rustls), and you haven’t enabled blocking mode, you may not be on the vulnerable code path. Verify this before relying on it, and note that changing concurrency models in production is risky.

3. Monitor and Detect

Watch for signs of the attack:

  • Unusually high CPU usage in Rustls-server processes, especially if it coincides with a spike in TLS handshake attempts.
  • A surge in half-open TLS sessions (connections stuck in handshake state).
  • Log entries showing ClientHello immediately followed by a closenotify alert, if your TLS logging captures that level of detail.

Set up proactive health checks that perform a full TLS handshake and request on a regular interval. If the service becomes unresponsive, you’ll get an alert even before customers notice.

4. Contain an Ongoing Attack

If you suspect you’re under attack:

  • Immediately block the offending source IPs at your network edge.
  • If the attack is distributed, engage your upstream DDoS mitigation service.
  • Consider temporarily draining traffic away from the affected service to a static page or patched failover instance.
  • Once the attack subsides, prioritize patching before restoring the service fully.

Outlook: After the Patch, What Comes Next

This incident is a stark reminder that memory safety isn’t a silver bullet. Logic bugs in state machines remain a threat even in Rust codebases. The Rustls community will likely invest more in handshake fuzzing and protocol conformance testing to catch similar edge cases in the future. Already, security researchers are scanning for other TLS libraries that might mishandle early close_notify alerts.

For operators, the lesson is clear: treat TLS termination as a critical security boundary. Regularly audit the TLS libraries you use, keep them updated, and have a plan to offload TLS processing to a known-good termination point when emergencies arise.

Expect proof-of-concept exploits to circulate within days, and opportunistic scanning to begin soon after. If you haven’t already inventoried your Rustls usage, do it today. The fix is simple—a version bump in most cases—but the cost of inaction could be a service outage that catches your team flat-footed.