Skip to main content
CVE Vulnerability Database

CVE-2026-9076: OpenSSL CMS Decryption DoS Vulnerability

CVE-2026-9076 is a denial of service vulnerability in OpenSSL CMS password-based decryption that triggers heap buffer over-reads. This article covers the technical details, affected systems, and mitigation strategies.

Published:

CVE-2026-9076 Overview

CVE-2026-9076 is a heap out-of-bounds read vulnerability in OpenSSL's Cryptographic Message Syntax (CMS) password-based decryption routine. The flaw resides in kek_unwrap_key() within crypto/cms/cms_pwri.c and is triggered when processing attacker-supplied CMS data using RFC 3211 PWRI (Password Recipient Info) key unwrap. An attacker can select a stream-mode Key Encryption Key (KEK) cipher via the keyEncryptionAlgorithm OID, bypassing the minimum-length guard intended for block ciphers. The resulting buffer over-read may crash applications that call CMS_decrypt() or CMS_decrypt_set1_password() on untrusted input. No password knowledge is required to trigger the read. FIPS modules are not affected. The issue is tracked under [CWE-125] Out-of-Bounds Read.

Critical Impact

Network-reachable applications decrypting attacker-supplied CMS data may crash, causing Denial of Service. No information disclosure occurs as over-read bytes are not returned to the attacker.

Affected Products

  • OpenSSL (CMS subsystem, non-FIPS builds) — see OpenSSL Security Advisory 20260609 for the exact version matrix
  • Applications invoking CMS_decrypt() or CMS_decrypt_set1_password() on untrusted CMS data
  • Tooling using openssl cms -decrypt -pwri_password ... against untrusted input

Discovery Timeline

  • 2026-06-09 - CVE-2026-9076 published to NVD
  • 2026-06-09 - OpenSSL publishes Security Advisory 20260609 with fix commits
  • 2026-06-10 - Last updated in NVD database

Technical Details for CVE-2026-9076

Vulnerability Analysis

The vulnerability stems from how kek_unwrap_key() validates the wrapping cipher before performing the RFC 3211 check-byte test. The function reads 7 bytes from a heap allocation sized using the wrapped key length carried in the CMS message. A minimum-length check guards this read, but the check uses the cipher's reported block length without verifying that the cipher is actually a block cipher.

When an attacker selects a stream-mode cipher through the PWRI keyEncryptionAlgorithm OID, the block-length-based guard is ineffective because stream ciphers report a block size of 1. The allocated buffer can then be smaller than the 7 bytes required for the check-byte test, producing a heap over-read.

The over-read remains contained inside the unwrap routine and its contents are not written to output. Triggering a crash requires the allocation to border an unmapped page, which is uncommon under default allocators. Network reachability and lack of authentication requirements make the issue suitable for opportunistic Denial of Service against decryption endpoints.

Root Cause

The root cause is an inadequate cipher-class validation in the key unwrap path. The check if (blocklen == 0) allowed blocklen values of 1 (stream ciphers) to pass, and the size guard inlen < 2 * blocklen becomes trivially satisfiable. The buffer sized from inlen can then be too small to hold the RFC-mandated 7 check bytes.

Attack Vector

An attacker crafts a CMS message containing a PWRI structure that references a stream-mode cipher OID for the KEK. The attacker submits this message to any service that calls CMS_decrypt() or CMS_decrypt_set1_password() with untrusted input. The over-read happens during the unwrap attempt, before any password authentication, so no credential knowledge is needed.

c
// Patch for crypto/cms/cms_pwri.c - kek_unwrap_key()
// Enforces a minimum block length of 4, rejecting stream-mode ciphers
     const unsigned char *in, size_t inlen,
     EVP_CIPHER_CTX *ctx)
 {
-    size_t blocklen = EVP_CIPHER_CTX_get_block_size(ctx);
+    int blocklen = EVP_CIPHER_CTX_get_block_size(ctx);
     unsigned char *tmp;
     int outl, rv = 0;

-    if (blocklen == 0)
+    if (blocklen < 4)
         return 0;

-    if (inlen < 2 * blocklen) {
+    if (inlen < 2 * (size_t)blocklen) {
         /* too small */
         return 0;
     }
-    if (inlen % blocklen) {
+    if (inlen > INT_MAX || inlen % blocklen) {
         /* Invalid size */
         return 0;
     }

Source: OpenSSL Commit 05b0663

Detection Methods for CVE-2026-9076

Indicators of Compromise

  • Unexpected crashes or SIGSEGV terminations in processes linking against libcrypto while handling CMS decryption requests
  • Inbound CMS messages whose PWRI keyEncryptionAlgorithm OID references a stream-mode cipher (for example RC4) rather than a block cipher (AES-KW, 3DES-KW)
  • Repeated decryption failures from a single source against endpoints exposing CMS_decrypt() or openssl cms -decrypt

Detection Strategies

  • Inventory applications and services that pass untrusted input to CMS_decrypt() or CMS_decrypt_set1_password() and confirm OpenSSL version
  • Inspect captured CMS payloads for non-block-cipher OIDs in the PWRI keyEncryptionAlgorithm field during DPI or mail/file scanning
  • Correlate process crash telemetry with preceding CMS decryption activity to identify exploitation attempts

Monitoring Recommendations

  • Enable core dump collection and crash reporting on services that perform CMS password-based decryption
  • Monitor for restart loops in mail gateways, document signing services, and PKI tooling that consume external CMS data
  • Alert on anomalous spikes in CMS decryption errors originating from untrusted networks

How to Mitigate CVE-2026-9076

Immediate Actions Required

  • Apply the fixed OpenSSL release listed in OpenSSL Security Advisory 20260609
  • Audit application code paths that call CMS_decrypt() or CMS_decrypt_set1_password() on attacker-controlled data and gate them behind input validation
  • Reject CMS messages whose PWRI keyEncryptionAlgorithm does not specify an approved block cipher key-wrap OID

Patch Information

OpenSSL released fixes in the following commits, which replace the weak blocklen == 0 check with blocklen < 4 and add an INT_MAX guard on inlen:

FIPS modules are not affected and do not require updates for this issue.

Workarounds

  • Disable PWRI password-based CMS decryption on services that do not require it
  • Pre-validate CMS structures at an application boundary and drop messages referencing non-block-cipher KEK OIDs
  • Run vulnerable decryption code in a sandboxed or restartable worker process to contain Denial of Service impact until patches are deployed
bash
# Verify the installed OpenSSL version against the advisory's fixed releases
openssl version -a

# Quick check: refuse CMS decrypt on untrusted input until patched
# (wrapper script - reject if PWRI OID is not an approved AES key wrap)
openssl asn1parse -in suspect.cms -inform DER \
  | grep -E 'OBJECT.*:(id-alg-PWRI-KEK|aes[0-9]+-wrap)' \
  || { echo 'Rejecting CMS: unapproved KEK algorithm'; exit 1; }

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.