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.
// 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
# 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.


