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



GHSA-8X3W-QJ7J-GQHF

The Shortest Path to Failure: Trivial Authentication Bypass in OpenMLS

Alon Barad
Alon Barad
Software Engineer

Feb 4, 2026·6 min read·18 visits

Executive Summary (TL;DR)

A critical flaw in the `openmls` library allowed attackers to bypass cryptographic verification by providing truncated or empty authentication tags. The issue stemmed from Rust's `.zip()` iterator, which silently stops comparing when the shortest input is exhausted. Fixed in v0.7.2.

In the world of cryptographic implementation, 'constant-time' comparison is the gold standard for preventing side-channel attacks. Developers bend over backward to ensure that checking a signature takes exactly the same amount of time, regardless of whether it's correct or not. But in a cruel twist of irony, the developers of `openmls`—a Rust implementation of the Messaging Layer Security (MLS) protocol—focused so hard on the timing that they forgot the length. Due to a quirk in how Rust's iterators handle zipping, the library's equality check would happily accept an empty byte array as a valid cryptographic tag. This allowed attackers to bypass message authentication entirely by simply providing... nothing.

The Hook: When Silence is Accepted

Messaging Layer Security (MLS) is the designated successor to the Double Ratchet protocol (used by Signal, WhatsApp, etc.), designed to bring end-to-end encryption to large groups efficiently. It is complex, math-heavy, and relies entirely on strict cryptographic verification. openmls is a prominent Rust implementation of this standard.

The core of any such system is the ability to verify that a message actually came from who it says it did. This is done via Message Authentication Codes (MACs) or confirmation tags. When a message arrives, the system calculates what the tag should be and compares it to what was received.

Usually, we worry about timing attacks here—where an attacker measures how long the comparison takes to guess the secret key byte-by-byte. The openmls team knew this. They wrote a equal_ct (constant-time equality) function to prevent it. Unfortunately, in their pursuit of side-channel safety, they opened a massive logical door: they stopped checking if the provided tag was actually the right size.

The Flaw: The Perils of Zipping

The vulnerability lies in a fundamental behavior of Rust's iterator system, specifically the .zip() method. In many languages, if you try to zip two arrays of different lengths, you might get an error or an exception. In Rust, .zip() is designed to be safe and lazy: it creates an iterator that yields pairs of elements until either of the two underlying iterators is exhausted.

This behavior is documented, standard, and usually desirable—except when you are comparing cryptographic secrets. The vulnerable function, equal_ct, took two byte slices (a and b) and zipped them together to check for differences.

If the attacker controls a (the input tag) and the system controls b (the expected secret tag), the attacker can simply provide an empty slice []. The .zip() iterator sees that a is empty and immediately stops. The loop body never executes. The difference accumulator variable, initialized to 0, remains 0. The function returns true. It's the cryptographic equivalent of a bouncer stepping aside because you didn't hand him an ID card to check.

The Code: The Smoking Gun

Let's look at the code that caused the issue. It's elegant, idiomatic Rust, and completely insecure.

The Vulnerable Code:

fn equal_ct(a: &[u8], b: &[u8]) -> bool {
    let mut diff = 0u8;
    // CRITICAL: .zip() stops at the shortest iterator
    for (l, r) in a.iter().zip(b.iter()) {
        diff |= l ^ r;
    }
    diff == 0
}

If a is empty, the loop runs 0 times. diff stays 0. 0 == 0 is true. Access granted.

The Fix:

The patch is painfully simple. Before doing the fancy constant-time loop, you must assert that the two things being compared are actually the same size. Since the length of a MAC is usually public knowledge (defined by the cipher suite), this check doesn't leak sensitive data.

fn equal_ct(a: &[u8], b: &[u8]) -> bool {
    // The Fix: Explicitly check lengths first
    if a.len() != b.len() {
        log::error!("Incompatible values");
        return false;
    }
 
    let mut diff = 0u8;
    for (l, r) in a.iter().zip(b.iter()) {
        diff |= l ^ r;
    }
    diff == 0
}

This addition ensures the loop always processes the full expected length of bytes, preventing the truncation attack.

The Exploit: The 'Null' Key

Exploiting this does not require a supercomputer or advanced math. It requires a debugger and the audacity to send nothing.

Scenario: You are an attacker sitting on the network (MITM) or a malicious member of a group. You want to inject a fake Commit message into the MLS group, which normally requires a valid ConfirmationTag.

  1. Craft the Payload: Create a valid MLS Commit message structure with your malicious content.
  2. Neutering the Tag: When the protocol asks for the ConfirmationTag (usually 32 bytes of high-entropy randomness), you provide a 0-byte array (or just an empty vector).
  3. Transmission: Send the packet to the victim client.
  4. Verification: The victim's openmls client receives the message. It calculates what the tag should be (e.g., 0xDEADBEEF...).
  5. The Bypass: It calls equal_ct(received_tag, expected_tag). Since received_tag is empty, the check passes instantly.
  6. Success: The client accepts your malicious commit, potentially rotating keys or adding compromised members to the group.

Alternatively, you could brute-force the first byte. If you send a 1-byte tag, you have a 1 in 256 chance of matching the first byte of the real tag. But why gamble when sending nothing wins 100% of the time?

The Impact: Trust No One

This is a catastrophe for a cryptographic library. The entire premise of MLS is that membership changes and message streams are cryptographically secured. By bypassing the equal_ct check, an attacker effectively disables authentication.

In a real-world scenario, this could allow:

  • Message Forgery: Injecting messages that appear to come from trusted group members.
  • Group Takeover: Forging Add or Remove proposals to kick out legitimate users or add attacker-controlled ghost users.
  • Denial of Service: corrupting the group state such that legitimate members can no longer decrypt messages.

This vulnerability is a stark reminder that "memory safety" (which Rust provides) does not equal "logic safety". The memory was never corrupted; the logic was simply flawed.

The Fix: Upgrade or Die

The fix was released in openmls v0.7.2. If you are using an older version, your application is wide open.

Remediation Steps:

  1. Open your Cargo.toml.
  2. Check the openmls version.
  3. Run cargo update -p openmls to pull the latest version.
  4. Verify in Cargo.lock that you are on at least 0.7.2.

If you cannot upgrade immediately, you must implement a wrapper around calls to openmls that explicitly validates the length of incoming tags before passing them to the library, though this is risky and difficult to cover 100% of code paths.

Official Patches

OpenMLSGitHub Commit fixing the vulnerability

Fix Analysis (1)

Technical Appendix

CVSS Score
9.8/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
EPSS Probability
0.04%

Affected Systems

Applications using openmls < 0.7.2Rust-based MLS implementations

Affected Versions Detail

Product
Affected Versions
Fixed Version
openmls
OpenMLS
< 0.7.20.7.2
AttributeDetail
CWECWE-1254 (Incorrect Comparison)
Attack VectorNetwork
CVSS9.8 (Critical)
ImpactAuthentication Bypass
LanguageRust
Fix Commit91ec049ffc2fa3766110223aa2aabe0303837af8

MITRE ATT&CK Mapping

T1557Adversary-in-the-Middle
Credential Access
T1212Exploitation for Credential Access
Credential Access
CWE-1254
Incorrect Comparison of Cryptographic Values

Vulnerability Timeline

Patch Committed to GitHub
2026-02-04
GHSA Advisory Published
2026-02-04

References & Sources

  • [1]GitHub Advisory
  • [2]Release Notes v0.7.2

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 21 hours ago•GHSA-G72G-R7M4-9X4G
6.3

GHSA-G72G-R7M4-9X4G: Insufficient Session Expiration of OAuth Tokens in NocoDB

NocoDB is subject to an insufficient session expiration vulnerability where OAuth access and refresh tokens are not invalidated or revoked during security-sensitive actions such as password changes, forgot-password requests, or password resets. This allows an attacker possessing an active OAuth token to maintain unauthorized persistence.

Amit Schendel
Amit Schendel
5 views•6 min read
•about 24 hours ago•GHSA-FGMC-2HQJ-86V4
6.9

GHSA-FGMC-2HQJ-86V4: Default Administrative Credentials in vantage6-server

A vulnerability in the vantage6 federated learning framework allows unauthenticated remote attackers to gain administrative control of the server via hardcoded default credentials (root/root) when deployed under default configurations in versions 4.2.3 and below.

Amit Schendel
Amit Schendel
6 views•5 min read
•1 day ago•GHSA-X9F6-9RVM-MMRG
6.9

GHSA-X9F6-9RVM-MMRG: Improper Access Control and Volume Mount Isolation Bypass in vantage6 Node

An improper access control vulnerability in the vantage6 node component allows concurrently running algorithm containers to read and modify sensitive input and output files of other tasks. The lack of strict workspace directory isolation exposes a significant attack surface in multi-tenant or federated environments where untrusted algorithms are executed.

Amit Schendel
Amit Schendel
3 views•4 min read
•1 day ago•CVE-2026-47760
8.7

CVE-2026-47760: Cross-Site Scripting (XSS) via SVG Namespace Sanitizer Bypass in TinyMCE

TinyMCE versions 6.8.0 through 7.0.1 contain a high-severity Cross-Site Scripting (XSS) vulnerability. The flaw exists in the custom HTML parser and sanitizer module, which incorrectly manages SVG namespace scopes when parsing nested elements. A low-privileged or unauthenticated attacker can submit a crafted HTML payload containing nested SVG structures to bypass sanitization filters, leading to arbitrary JavaScript execution in the context of the victim's browser session.

Alon Barad
Alon Barad
12 views•7 min read
•1 day ago•CVE-2026-47759
8.7

CVE-2026-47759: Stored Cross-Site Scripting (XSS) via Unsanitized data-mce-* Serialization Bypass in TinyMCE

CVE-2026-47759 is a critical stored Cross-Site Scripting (XSS) vulnerability affecting multiple active branches of the TinyMCE rich text editor. The flaw resides in the editor's handling of user-controlled, prefixed internal attributes, such as data-mce-href, data-mce-src, and data-mce-style. When processing raw HTML inputs, TinyMCE's internal validation schema neglects to inspect these custom prefixed attributes. During HTML serialization, the editor's engine extracts these unsanitized values and copies them back into standard executable attributes, overwriting any previously sanitized standard values and leading to execution of arbitrary code.

Amit Schendel
Amit Schendel
8 views•7 min read
•1 day ago•CVE-2026-47762
8.7

CVE-2026-47762: Stored Cross-Site Scripting (XSS) in TinyMCE Protect Pattern Restoration

A high-severity stored Cross-Site Scripting (XSS) vulnerability was identified in the TinyMCE rich text editor. The flaw exists in the handling of the 'protect' configuration option, where forged placeholder comments containing malicious payloads bypass the editor's sanitization routines and execute arbitrary JavaScript during serialization and content restoration.

Amit Schendel
Amit Schendel
7 views•8 min read