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-21895

One is the Loneliest Number: Crashing Rust's RSA Crate

Alon Barad
Alon Barad
Software Engineer

Feb 24, 2026·6 min read·56 visits

Executive Summary (TL;DR)

The `rsa` crate (< 0.9.10) failed to validate that prime factors ($p$ and $q$) were strictly greater than 1. By submitting a crafted RSA key where a prime is set to `1`, an attacker can force the library to attempt modular arithmetic with a modulus of zero (or similar invalid operations), triggering a thread-killing panic. This affects downstream projects like `rPGP`, effectively allowing remote unauthenticated attackers to crash applications processing PGP keys.

A logic error in the validation of RSA private key components within the `rsa` Rust crate allows attackers to trigger a Denial of Service (DoS) by supplying the integer `1` as a prime factor. While Rust is famed for memory safety, it cannot save developers from basic arithmetic fallacies; specifically, allowing a prime factor of 1 results in division-by-zero panics deep within the cryptographic math engine.

The Hook: The Integrity of One

In the realm of cryptography, we obsess over large numbers. We want our primes to be massive, un-factorable giants that would take the heat death of the universe to reverse-engineer. But in our quest for bigness, we often forget to check the basement. What happens when the numbers are too small? Specifically, what happens when a prime factor is the multiplicative identity: the number 1?

The rsa crate is the de facto standard for pure-Rust RSA implementations. It is memory-safe, fast, and generally robust. However, even the safest languages allow you to shoot yourself in the foot if you ignore the laws of mathematics. RSA relies on the premise that $n = p \times q$, where $p$ and $q$ are distinct primes. If $p=1$, the math doesn't just get weak; it breaks fundamental assumptions of the algorithm.

This vulnerability isn't a complex buffer overflow or a heap grooming masterpiece. It's a failure to ask a simple question: "Is this number actually big enough to be a prime?" The answer, for versions prior to 0.9.10, was a resounding "meh, close enough."

The Flaw: Math is Hard, Bounds Checks are Harder

The vulnerability lies within src/key.rs, specifically in RsaPrivateKey::from_components. When constructing a private key from raw components (modulus, public exponent, private exponent, and primes), the library performs a sanity check to ensure the inputs are valid. Or at least, it tries to.

Here is the logic that was supposed to protect us:

// The offending code
for prime in &self.primes {
    if *prime < BigUint::one() { 
        // This only catches 0, not 1
        return Err(Error::InvalidPrime);
    }
    m *= prime;
}

Do you see it? The code checks if the prime is strictly less than one. In integer arithmetic, the only non-negative integer strictly less than 1 is 0. If an attacker passes 1, the check 1 < 1 evaluates to false, and the loop continues happily, accepting 1 as a valid prime factor.

Why does this matter? Because RSA private key operations—specifically the Chinese Remainder Theorem (CRT) optimizations—rely on calculating values modulo $(p-1)$. If $p=1$, then $(p-1)=0$. You don't need a PhD in math to know that modulo zero is a one-way ticket to Panic City.

The Code: The Smoking Gun

The fix, applied in commit 2926c91bef7cb14a7ccd42220a698cf4b1b692f7, is almost embarrassingly simple. It transforms a loose check into a strict boundary.

The Vulnerable Logic:

if *prime < BigUint::one() {
    return Err(Error::InvalidPrime);
}

The Fixed Logic:

if *prime <= BigUint::one() {
    return Err(Error::InvalidPrime);
}

By adding that single equals sign (=), the developers ensured that 1 is rejected. Additionally, the patch included an upgrade to the underlying num-bigint-dig library (from 0.8.4 to 0.8.6), which hardened the BigInt arithmetic against internal panics. This two-pronged approach fixed the logic error at the gate and reinforced the walls against the crash.

The Exploit: Panic at the Keyring

To exploit this, we don't need a debugger or a shellcode encoder. We just need a text editor or a simple script to modify a serialized key. The most prominent target for this exploit is the PGP ecosystem, specifically applications using the pgp crate (which depends on rsa).

The Attack Chain:

  1. Craft the Packet: The attacker generates a standard OpenPGP Secret Key packet. These packets contain the RSA private key components.
  2. The Modification: The attacker locates the bytes corresponding to prime1 (p) or prime2 (q) and overwrites them to represent the integer 1.
  3. Delivery: The attacker uploads this "poisoned" key to a keyserver, sends it via email to an automated gateway, or simply serves it to a client application.
  4. The Crash: When the victim application parses the packet, it calls RsaPrivateKey::from_components. The validation passes (because $1 \not< 1$). The application then attempts to use the key. As soon as it attempts to calculate CRT parameters (like $dP = d \pmod{p-1}$), the BigUint library attempts a division by zero.

In Rust, a division by zero in the main thread (or an uncaught thread) results in a panic!. The process terminates immediately. For a web server or a key processing daemon, this is a total service outage.

The Impact: Why Should We Panic?

You might look at the CVSS score of 2.7 (assigned by some CNAs) and think, "Low severity? I'll patch it next month." Do not be deceived. That score assumes a generic context where the attacker has no path to the vulnerability. In the real world, cryptographic libraries parse untrusted data by design.

If you are running an OpenPGP keyserver, an email encryption gateway, or an identity provider that accepts user-uploaded certificates, this is a Critical vulnerability. A single malicious packet can take down your entire ingestion pipeline. Since Rust panics unwind the stack, unless you have extremely robust panic catching at the worker level (which many async runtimes do, but not all logic paths guarantee), your service goes dark.

It is a trivial, asymmetric attack: low effort for the attacker, high availability impact for the defender. It turns your robust Rust application into a fragile house of cards.

The Fix: Restoring Sanity

The remediation is straightforward, thanks to Rust's package management. You need to ensure your dependency tree is using a safe version of the rsa crate.

Immediate Action: Run the following in your project root:

cargo update -p rsa

Verify that Cargo.lock shows rsa version 0.9.10 or higher.

For Downstream Users: If you use rPGP or other high-level wrappers, check their advisories. Most have already bumped their dependency versions. If you are pinning dependencies (bad practice, but it happens), unpin them to allow the patch to flow through.

> [!NOTE] > If you cannot upgrade immediately, you must implement manual validation of all RSA components before passing them to the rsa crate. Ensure p > 1 and q > 1.

Official Patches

RustCryptoCommit fixing the prime validation logic

Fix Analysis (1)

Technical Appendix

CVSS Score
7.5/ 10
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N/E:P
EPSS Probability
0.02%
Top 95% most exploited

Affected Systems

Rust `rsa` crate < 0.9.10rPGP (Rust OpenPGP implementation)RustCrypto ecosystem downstream consumers

Affected Versions Detail

Product
Affected Versions
Fixed Version
rsa
RustCrypto
< 0.9.100.9.10
pgp
rPGP
Affected via dependencyDependent on rsa update
AttributeDetail
CWE IDCWE-703
Attack VectorNetwork (Remote)
CVSS Base7.5 (High - Downstream)
ImpactDenial of Service (Panic)
Exploit StatusPoC Available
Root CauseIncorrect Comparison Operator

MITRE ATT&CK Mapping

T1499.004Endpoint Denial of Service: Application Exhaustion
Impact
T1552.004Unsecured Credentials: Private Keys
Credential Access
CWE-703
Improper Check or Handling of Exceptional Conditions

Improper Check or Handling of Exceptional Conditions

Known Exploits & Detection

Research ReportPanic at the Keyring: Exploiting RSA crate validation logic

Vulnerability Timeline

Patch committed to RSA repository
2026-01-06
CVE-2026-21895 Published
2026-01-08
Downstream rPGP advisory published
2026-02-13
Public PoC details released
2026-02-14

References & Sources

  • [1]GHSA Advisory for RSA Crate
  • [2]GHSA Advisory for rPGP

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 19 hours ago•GHSA-7PPR-R889-MCF2
7.5

GHSA-7PPR-R889-MCF2: Unbounded WebSocket Message Aggregation in http4s-blaze-server leads to Denial of Service

An uncontrolled resource consumption vulnerability exists in the Scala-based http4s-blaze-server package of the http4s/blaze library. The vulnerability allows remote, unauthenticated attackers to cause an Out of Memory Error (OOM) and JVM crash by streaming a continuous sequence of small or empty WebSocket continuation frames with the FIN bit set to 0. This bypasses typical payload size checks because of the JVM's per-object allocation overhead, leading to rapid heap exhaustion with minimal network bandwidth.

Alon Barad
Alon Barad
6 views•5 min read
•about 20 hours ago•GHSA-95CV-R8X4-VH75
7.6

GHSA-95cv-r8x4-vh75: Path Traversal Vulnerability in OpenList Batch Rename Handler

A critical path traversal vulnerability has been identified in the OpenList Go-based backend package. The vulnerability exists within the batch rename handler because the application does not validate the source filename parameter before constructing filesystems paths. This omission allows authenticated users to escape their designated directory and rename files in sibling paths.

Amit Schendel
Amit Schendel
7 views•7 min read
•about 21 hours ago•GHSA-P6PH-3JX2-3337
4.3

GHSA-P6PH-3JX2-3337: Horizontal Privilege Escalation and Metadata Information Disclosure via Bleve Search in OpenList

OpenList version 4.2.3 and prior is vulnerable to an authorization bypass and metadata leakage. When configured with the Bleve search engine backend, OpenList fails to perform separator-aware path matching when validating tenant containment. This allows authenticated users to access sibling directories sharing similar name prefixes. Furthermore, the search backend returns unfiltered global result counts, leaking existence verification data of unauthorized files via side-channel analysis.

Amit Schendel
Amit Schendel
7 views•5 min read
•about 22 hours ago•GHSA-86CX-WWF4-PHQ4
6.5

GHSA-86cx-wwf4-phq4: Path Prefix Confusion Authorization Bypass in OpenList

An authorization bypass vulnerability in OpenList version 4.2.3 and below allows authenticated users to read arbitrary files outside of their designated base directories due to an insecure path prefix check using Go's standard strings.HasPrefix function.

Amit Schendel
Amit Schendel
6 views•6 min read
•about 23 hours ago•CVE-2026-16584
7.0

CVE-2026-16584: Security Policy Bypass in AWS API MCP Server via Startup Initialization Failure

A security policy bypass vulnerability exists in the AWS API MCP Server (awslabs-aws-api-mcp-server) from version 0.2.13 through 1.3.46. When the server fails to load the read-only operations index during startup (due to transient network failures, file permission issues, or other exceptions), it logs a warning but continues running in an insecure, degraded state. Under this condition, the security policy engine fails open, silently skipping all subsequent security checks and consent prompts for the lifetime of the process. This permits unauthorized mutating AWS CLI commands to execute via indirect prompt injection attacks.

Amit Schendel
Amit Schendel
8 views•7 min read
•1 day ago•GHSA-6V4M-FW66-8R4X
6.5

GHSA-6V4M-FW66-8R4X: Path Disclosure and Shell Expansion Bypass in Shescape

An incomplete escaping vulnerability in the npm package 'shescape' allows unauthenticated users to trigger dynamic shell expansions, absolute path disclosure, and command block break-outs on Unix and Windows systems.

Alon Barad
Alon Barad
6 views•7 min read