CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-24785

The Sound of Silence: Breaking Clatter's Post-Quantum Promises (CVE-2026-24785)

Amit Schendel
Amit Schendel
Senior Security Researcher

Jan 28, 2026·7 min read·31 visits

Executive Summary (TL;DR)

Clatter < 2.2.0 implemented 'psk0' handshake patterns incorrectly. It used static Pre-Shared Keys to encrypt data before establishing ephemeral randomness. This turns a fancy Post-Quantum encryption tunnel into a static substitution cipher, allowing anyone with the PSK (or a reused stream) to decrypt the entire session.

A critical protocol compliance failure in the Clatter Rust library allows attackers to decrypt Post-Quantum Noise sessions. By violating the Noise Protocol's PSK Validity Rule, specific handshake patterns fail to mix ephemeral entropy before encryption, leading to catastrophic key reuse.

The Hook: When Quantum Meets Basic Arithmetic

We live in an era where everyone is terrified of the 'Quantum Apocalypse.' Developers are scrambling to slap 'Post-Quantum' (PQ) stickers on their cryptographic libraries like it's organic produce. Enter Clatter: a no_std friendly Rust implementation of the Noise Protocol Framework that promised to secure your embedded devices against computers that don't even really exist yet.

But here is the irony: while Clatter was busy looking 20 years into the future at Shor's algorithm, it tripped over a rule written in the present. Specifically, it ignored the PSK Validity Rule (Section 9.3 of the Noise spec).

In the world of cryptography, randomness is god. If you encrypt something without randomness, you aren't encrypting—you're just encoding. CVE-2026-24785 exposes a fundamental flaw in how Clatter handled Pre-Shared Keys (PSKs) in specific handshake patterns. By processing the PSK too early—before the ephemeral keys were mixed in—Clatter inadvertently created encryption keys that were entirely deterministic based on static secrets. If you thought your noise_pqnn_psk0 tunnel was safe from the NSA's quantum computer, I have bad news: it wasn't even safe from a script kiddie with a Python script.

The Flaw: The Sin of Premature Encryption

To understand this bug, you need to understand the 'State Machine' of a Noise handshake. Noise relies on a SymmetricState that acts like a rolling snowball. Every time you send a token (like a public key or a PSK), it gets mixed into the snowball (ChainingKey). When you want to encrypt a message, you carve a chunk off that snowball to make an encryption key.

The Noise Protocol Framework has a Golden Rule for PSKs: Thou shalt not encrypt until thou hast randomness. specifically:

> "Parties must not send any encrypted data (including their static public keys) after processing a psk token unless they have also sent an ephemeral public key (e or ekem)."

Why? Because a PSK is static. If I derive an encryption key solely from ProtocolName + PSK, that key is the same every single time the protocol runs. This destroys forward secrecy and introduces nonce reuse issues.

Clatter implemented patterns like noise_pqnn_psk0. The psk0 modifier means the PSK is the very first thing processed. In Clatter's vulnerable versions, the library would take the PSK, mix it in, and then immediately allow the Initiator to encrypt a payload or a static key.

Critically, at this stage, no ephemeral key exchange (e or ekem) has occurred. The encryption key is derived purely from static data. If an attacker knows the PSK (which is often shared across a fleet of devices) or if the PSK is ever compromised, they can decrypt the first flight of messages retroactively. Worse, because the state is deterministic, the keystream reuse is catastrophic.

The Code: Reading the Rust

The fix landed in commit b65ae6e9b8019bed5407771e21f89ddff17c5a71. The developers had to essentially introduce a 'runtime cop' to police the handshake patterns.

Previously, Clatter blindly followed the pattern string. If the string said psk -> encrypt, Clatter asked "how high?". The patch introduces validate_psk_rule inside handshakepattern.rs. Here is the logic simplified:

// The new Sheriff in town
fn validate_psk_rule(pattern: &HandshakePattern) -> Result<(), PatternError> {
    let mut psk_sent = false;
    let mut entropy_mixed = false;
 
    for token in pattern.tokens {
        match token {
            Token::Psk => psk_sent = true,
            // Ephemeral keys provide the required entropy
            Token::E | Token::Ekem => entropy_mixed = true,
            // If we try to encrypt (S, Skem, or payload) ...
            Token::S | Token::Skem => {
                // ... and we have a PSK but no entropy ...
                if psk_sent && !entropy_mixed {
                    // ... JAIL.
                    return Err(PatternError::PskValidityViolation);
                }
            }
            _ => {}
        }
    }
    Ok(())
}

They also nuked the offending patterns from the library's registry. Patterns like noise_pqkk_psk0 and noise_pqnn_psk0 are gone. They didn't just fix the code; they removed the foot-guns entirely.

Furthermore, in the write_message function, they added a runtime check. Even if you manually constructed a bad pattern, the library now tracks own_randomness_applied. If you try to write a payload while psk_applied is true but own_randomness_applied is false, it panics (or returns an error, because this is Rust, not C++).

The Exploit: Decrypting the 'Secure' Tunnel

Let's walk through a realistic attack scenario. Imagine an IoT fleet using Clatter for secure command and control. They use the pattern noise_pqnn_psk0 because they want 'Post-Quantum' security (pq) and they want authentication via a Pre-Shared Key (psk).

The Setup:

  1. Initiator (IoT Bulb) starts the handshake.
  2. Pattern: psk0 -> psk, payload.
  3. State: ChainingKey = Hash(ProtocolName || PSK).
  4. Action: Initiator encrypts its generic "Hello" payload using a key derived from that ChainingKey.

The Attack:

  1. Passive Interception: I record the traffic. I see the handshake packet.
  2. Knowledge: I managed to dump the firmware of one lightbulb and extracted the fleet-wide PSK (a common sin in IoT).
  3. Decryption: Since I have the PSK and the Protocol Name is public, I can calculate the exact same ChainingKey the lightbulb generated.
  4. Result: I derive the encryption key. I decrypt the payload.

Wait, it gets worse. Because there is no random nonce (ephemeral key) mixed in yet, if the lightbulb reboots and sends the exact same "Hello" message, the ciphertext will be identical. This allows for trivial replay attacks and traffic analysis even without the PSK, purely based on the deterministic nature of the output. The 'Post-Quantum' protection is irrelevant because the math failed at step zero.

The Impact: Why Post-Quantum Didn't Save You

The severity of this is High (CVSS 8.0) for a reason. While it doesn't allow unauthenticated RCE directly, it completely negates the confidentiality and integrity guarantees of the encrypted channel during the initial phase.

For psk0 patterns, the Forward Secrecy property is non-existent until the second flight of messages. If the PSK is compromised, all past and future sessions that relied on that PSK for the initial flight are readable.

This is particularly damning for '0-RTT' style optimisations where data is sent in the first message. If your application sends sensitive credentials, API keys, or critical commands in that first packet, they are effectively sent in plaintext to anyone with the PSK.

In the context of the noise_pq* patterns, the irony is palpable: users selected these patterns specifically for higher security against future threats, only to be vulnerable to present-day logic errors.

Mitigation: Silence the Noise

If you are using Clatter, you have two options:

  1. The Good Way: Upgrade to version 2.2.0. The maintainers have done the heavy lifting. They've removed the broken patterns and added runtime checks that will scream at you if you try to define a custom broken pattern.

  2. The 'I Can't Upgrade' Way: If you are stuck on an older version (maybe burned into ROM), you MUST change your configuration. Do not use psk0 patterns. Switch to psk2 (where the PSK is added at the end of the handshake) or ensuring that your custom pattern sends an e token before the psk token.

Developer Lesson: Implementing a spec like Noise is not just about getting the math right; it's about adhering to the state machine's safety properties. Always validate that your state transitions don't leave you naked before you step outside.

Official Patches

ClatterCommit fixing the PSK validity rule violation

Fix Analysis (1)

Technical Appendix

CVSS Score
8.0/ 10
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N/E:U
EPSS Probability
0.01%
Top 97% most exploited

Affected Systems

Rust applications using Clatter < 2.2.0Embedded systems using Clatter with `psk0` patternsPost-Quantum VPN implementations using Clatter

Affected Versions Detail

Product
Affected Versions
Fixed Version
Clatter
Clatter Maintainers
< 2.2.02.2.0
AttributeDetail
CWE IDCWE-327
Attack VectorNetwork
CVSS Score8.0 (High)
ImpactConfidentiality & Integrity Loss
EPSS Score0.00015
Vulnerability TypeCryptographic Logic Error

MITRE ATT&CK Mapping

T1557Adversary-in-the-Middle
Credential Access
T1040Network Sniffing
Credential Access
T1552Unsecured Credentials
Credential Access
CWE-327
Broken Cryptography

Use of a Broken or Risky Cryptographic Algorithm

Known Exploits & Detection

HypotheticalExploitation involves capturing handshake packets and deriving keys using known PSK.

Vulnerability Timeline

Patch Committed (b65ae6e9)
2026-01-27
GHSA-253q-9q78-63x4 Published
2026-01-27
CVE-2026-24785 Assigned
2026-01-28

References & Sources

  • [1]Noise Protocol Framework - Section 9.3
  • [2]GHSA-253q-9q78-63x4 Advisory

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•about 2 hours ago•CVE-2026-48861
2.1

CVE-2026-48861: HTTP Request Splitting and Smuggling via Method Parameter CRLF Injection in Elixir Mint

CVE-2026-48861 is a client-side HTTP request-line CRLF (Carriage Return Line Feed) injection vulnerability in the popular Elixir HTTP client library, Mint. The vulnerability permits HTTP Request Splitting and HTTP Request Smuggling when an application forwards untrusted, attacker-controlled inputs to Mint's HTTP client requests as either the HTTP request method or target. By embedding CRLF characters within these parameters, an attacker can terminate the request line prematurely, inject malicious headers, or pipeline entirely independent requests. These smuggled requests are then processed by upstream or downstream proxy servers as separate HTTP queries on the same TCP connection. While Mint version 1.7.0 introduced target validation to secure the request target, the HTTP request method parameter remained completely unvalidated. This flaw allows attackers to bypass routing filters, access restricted internal APIs, or poison HTTP caches under default configurations.

Amit Schendel
Amit Schendel
3 views•7 min read
•about 3 hours ago•CVE-2026-49753
6.3

CVE-2026-49753: HTTP Request/Response Smuggling via Inconsistent Content-Length Parsing in Elixir Mint Client

An Inconsistent Interpretation of HTTP Requests (HTTP Request/Response Smuggling) vulnerability in the Elixir Mint HTTP client allows attacker-controlled HTTP/1 servers to desynchronize response framing on shared connections due to over-lenient parsing of sign-prefixed Content-Length headers.

Amit Schendel
Amit Schendel
5 views•6 min read
•about 3 hours ago•CVE-2026-49754
8.2

CVE-2026-49754: Denial of Service via Unbounded HTTP/2 CONTINUATION Frame Accumulation in Elixir Mint

An allocation of resources without limits or throttling vulnerability in Elixir Mint allows an attacker-controlled HTTP/2 server to exhaust memory in a Mint client. The vulnerability is exploited by sending a HEADERS frame without the END_HEADERS flag followed by an infinite stream of CONTINUATION frames. Because the client lacks limits on the incoming header-block accumulator, the client continuously consumes memory until an out-of-memory crash occurs.

Amit Schendel
Amit Schendel
6 views•6 min read
•about 4 hours ago•CVE-2026-48596
2.1

CVE-2026-48596: Improper Neutralization of CRLF Sequences in Elixir Tesla Multipart HTTP Client

CVE-2026-48596 is an Improper Neutralization of CRLF Sequences in HTTP Headers (HTTP Request/Response Splitting, CWE-113) in the Elixir Tesla HTTP client. The flaw resides in how multipart content-type parameters are joined and serialized, enabling attackers to inject arbitrary headers or split HTTP requests when applications pass untrusted inputs to the parameters of multipart uploads.

Alon Barad
Alon Barad
4 views•6 min read
•about 4 hours ago•CVE-2026-48594
8.2

CVE-2026-48594: Decompression Bomb Denial of Service in Elixir Tesla HTTP Client

An improper handling of highly compressed data (decompression bomb) vulnerability exists in the Elixir Tesla HTTP client when utilizing response decompression middlewares. By serving highly compressed responses or stacked content-encoding headers, a malicious server can cause arbitrary heap exhaustion, leading to a denial of service (DoS) crash in the BEAM virtual machine.

Amit Schendel
Amit Schendel
5 views•6 min read
•about 5 hours ago•CVE-2026-48595
8.2

CVE-2026-48595: Cross-Origin Credential Leakage in Elixir Tesla Client via Case-Sensitive Redirect Filter Bypass

A high-severity security vulnerability in Elixir's Tesla HTTP client library (CVE-2026-48595) allows unauthenticated remote attackers to harvest sensitive credentials, including Authorization headers and cookies. The flaw resides in the 'Tesla.Middleware.FollowRedirects' component, which performs case-sensitive lookups when stripping credentials during cross-origin redirects. Because HTTP headers are case-insensitive by RFC specifications, standard canonical casing (e.g., 'Authorization') bypasses the lowercase-only blocklist, leaking tokens to untrusted external redirect destinations.

Alon Barad
Alon Barad
5 views•5 min read