Rustls 0.23.45 fixes a TLS 1.3 flaw open since 2024
Versions 0.23.13 through 0.23.44 accepted TLS 1.3 handshake messages at the wrong encryption level, a bug introduced in September 2024.
3 min read

By the numbers
- the Rustls release that contains the fix
- 0.23.45
- the oldest affected version, from September 2024
- 0.23.13
- the bug sat in released code before the fix
- 2 years
Rustls 0.23.45 shipped on September 14, 2026 with a fix for a TLS 1.3 handshake bug that had been in released code for about two years. Every version from 0.23.13 to 0.23.44 is affected, so anyone depending on Rustls should check which version their build actually resolves to. Phoronix reported the release, and the project filed the details as advisory GHSA-2mjx-qc3c-rqvc.
Rustls is a TLS library written in Rust. TLS is the protocol behind HTTPS, and a TLS library is what your program uses to set up an encrypted connection. Rustls is a common choice in Rust services that want to avoid OpenSSL.
What the flaw actually allows
Partway through a TLS 1.3 handshake, both sides change keys. Messages sent after that change are supposed to be encrypted with the new key. Rustls did not always enforce it.
The advisory is specific about the condition. Rustls accepted handshake messages sent at the wrong encryption level when they followed a key-changing message inside the same record. A record is the chunk the protocol actually puts on the wire, so several handshake messages can travel together.
The honest read is that this is narrower than it first sounds. "The handshake transcript is still authenticated," the announcement says, which means an attacker in a network position cannot use this to alter a handshake or complete one they should not. The practical effect is that a peer could send in plaintext something the protocol requires to be encrypted, and Rustls would not reject the connection.
So this is a strictness bug rather than a broken authentication check. That still matters. A library that accepts messages the specification forbids is a library whose behavior diverges from RFC 8446, and divergence is where interoperability bugs and later exploits come from.
Memory safety was never the whole job
Phoronix draws the useful conclusion, and it is worth stating plainly. Rustls exists partly because memory-unsafe TLS code has a long history of serious bugs, and Rust removes that class of defect. This bug is not in that class.
Nothing about Rust prevents a protocol state machine from accepting a message it should have refused. That is a logic error, and logic errors survive any choice of language. A rewrite in a safe language buys you freedom from buffer overflows and use-after-free, not freedom from misreading a specification.
This site has made the same point from the other direction: a Rust package was the vehicle for a build-time supply chain attack on arrayref. The language is one layer of defense, and only one.
Which versions to check
| Version | Status |
|---|---|
| 0.23.13 through 0.23.44 | Affected |
| 0.23.45 | Fixed |
| Before 0.23.13 | Predates the change that introduced the bug, per the advisory |
The bug was introduced in September 2024, which is why the affected range starts at 0.23.13 rather than at the beginning. The issue is also tracked as GO-2026-4340.
What this means for developers
Upgrade, then find out what you were actually running. Those are two separate jobs and the second is the one people skip.
Run cargo update -p rustls and confirm you land on 0.23.45 or later. Then run cargo tree -i rustls to see what pulled it in. Rustls is usually an indirect dependency, arriving through an HTTP client or a server framework, so the version you get is decided by whatever those crates allow. A transitive pin in a library you do not control is the common reason an upgrade appears to do nothing.
If you ship a binary rather than a service, check the lockfile you actually built from, not the one on your machine today. Wiring cargo audit into CI is worth doing whether or not this bug affects you, and it will flag the advisory once its database carries it.
Do not spend the afternoon on incident response for this one. There is no evidence in either source of exploitation, and the advisory itself says the transcript stays authenticated, which rules out the scariest reading. Treat it as a routine dependency bump with a real deadline rather than an emergency.
The wider lesson is about how long a quiet protocol bug can live. This one sat in shipped releases for two years, in a library chosen specifically for its safety properties, and it was found by review rather than by an incident. That is the system working, and it is also a reminder that "written in Rust" is a claim about one category of bug and nothing more.
Sources
- Rustls 0.23.45 Released To Fix Two Year Old Security Issue - Phoronix
- GHSA-2mjx-qc3c-rqvc - rustls on GitHub
Related articles

Rust supply chain attack slips build-time malware into arrayref
Malicious versions of arrayref, internment, and append-only-vec ran a remote payload during cargo build for under two hours before crates.io removed them.

Rust is now a tier-1 language at Microsoft
Microsoft made Rust a tier-1 language beside C++, C# and TypeScript. More than 100 of its repositories now build Rust code.

A tampered strip binary can backdoor all of NixOS
Researchers built Ken Thompson's trusting-trust attack out of GNU strip, not a compiler, and used it to backdoor almost every binary in a NixOS installer.
The daily brief
Three to five stories a day, and what each one means for the people who build software. Free, no spam.