Someone left a loaded gun in the junk drawer — it only fires if you open that specific drawer, but the whole house is past its warranty
CVE-2026-45447 is a heap use-after-free in OpenSSL's PKCS7_verify() function. When a specially crafted PKCS#7 or S/MIME signed message arrives with an empty SignedData.digestAlgorithms ASN.1 SET, OpenSSL frees a caller-owned BIO while the application still holds a reference. Depending on heap allocator behavior, this yields crashes, heap corruption, or potentially attacker-controlled code execution. It affects every OpenSSL release line — 1.0.2 through 4.0 — but the fix for 1.1.1 (version 1.1.1zh) is only available through paid extended support because 1.1.1 went EOL in September 2023. The remaining four CVEs in this plugin (CVE-2026-7383, CVE-2026-34180, CVE-2026-42766, CVE-2026-9076) are all rated Low by OpenSSL and require impractical preconditions like half-a-gigabyte attacker-controlled strings or >2 GB ASN.1 primitive elements.
The user-reported vendor severity of MEDIUM understates the risk. OpenSSL's own advisory rates CVE-2026-45447 as High (CVSS 8.1, AC:H), and Tenable's VPR of 7.6 (98th percentile) agrees. The MEDIUM label likely comes from an aggregated bulletin (e.g., HKCERT) that averages across all 18 CVEs in the June 2026 advisory. That averaging hides the headline bug. The four Low-severity CVEs are noise — the entire plugin's priority should be driven by CVE-2026-45447 and the fact that you're running a library three years past end-of-life.
4 steps from start to impact.
Deliver crafted PKCS#7 / S/MIME message
SignedData structure with the digestAlgorithms field present as an empty ASN.1 SET. This payload is delivered as an S/MIME email attachment, a signed document, or any data stream processed by an application calling PKCS7_verify(). No authentication is required. The PoC structure is trivial to generate with standard ASN.1 tooling.- Target application must call
PKCS7_verify()(not CMS APIs) on attacker-controlled input - Network path to deliver the message (email, HTTP upload, API endpoint)
- Most modern applications have migrated to CMS APIs — only legacy PKCS#7 callers are affected
- The TLS stack does not call
PKCS7_verify(), so HTTPS endpoints are not directly exploitable via handshake
Trigger use-after-free in PKCS7_verify()
PKCS7_verify(), OpenSSL encounters the empty digestAlgorithms SET and frees the caller-owned BIO object. The calling application is not notified. On the next use or deallocation of that BIO by the application, a use-after-free condition occurs. This is deterministic — the empty SET always triggers the incorrect free.- Application must actually invoke signature verification on the untrusted input (not just parse headers)
- Some applications validate ASN.1 structure before calling
PKCS7_verify(), which may reject the empty SET - Applications that discard the BIO immediately after verification reduce the exploitation window
Achieve heap corruption or crash
- Heap allocator must reallocate the freed region in a predictable way for controlled exploitation
- Modern glibc heap hardening (tcache key checks, safe-linking in glibc ≥2.32) and ASLR make controlled exploitation significantly harder
- CVSS rates this AC:H for exactly this reason
Escalate to remote code execution
- Favorable heap layout (application-specific, requires target profiling)
- No memory-safety mitigations intercepting the corrupted pointer (CFI, shadow stacks)
- No known weaponized exploit in the wild
- Heap grooming across a network boundary (S/MIME, HTTP) adds significant unreliability
- Control-flow integrity in hardened builds (e.g., Fedora/RHEL with
-fcf-protection) blocks vtable hijack
The supporting signals.
| In-the-wild exploitation | Not observed. No confirmed campaigns. Not listed in CISA KEV as of 2026-09-21. No GreyNoise or Shadowserver tags for this CVE. |
|---|---|
| Proof of concept | Crash PoC available. 0xBlackash/CVE-2026-45447 — bash script demonstrating the crash path. Authors explicitly exclude weaponized exploit code. No public RCE exploit chain. |
| EPSS | 3.57% (88.8th percentile) — elevated probability of exploitation within 30 days relative to all CVEs, but well below the ~6%+ threshold that typically correlates with imminent weaponization. |
| CISA KEV | Not listed as of 2026-09-21. |
| CVSS vector | CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H — 8.1 HIGH. Network-reachable, no auth, no user interaction, but Attack Complexity: High reflects the heap exploitation difficulty. Scope unchanged. |
| Affected versions | OpenSSL 1.1.1 through 1.1.1zg. Also affects 1.0.2–1.0.2zp, 3.0.0–3.0.20, 3.4.0–3.4.5, 3.5.0–3.5.6, 3.6.0–3.6.2, 4.0.0. Only PKCS#7 API callers — CMS API users are not affected. |
| Fixed versions | 1.1.1zh (extended support only). Mainstream fixes: 3.0.21, 3.4.6, 3.5.7, 3.6.3, 4.0.1. Distro backports: RHSA-2026:66524 (RHEL), Ubuntu USN tracking, SUSE advisory pending. |
| Exposure footprint | OpenSSL 1.1.1 went EOL September 2023. Shodan historically showed ~16K publicly accessible servers advertising 1.1.1 banners, though many are behind load balancers. The real footprint is internal — embedded in appliances, legacy app servers, and IoT firmware. |
| Disclosure date | 2026-06-09 — OpenSSL Security Advisory covering 18 CVEs across all supported branches. |
| Credited researcher | Not publicly attributed in the OpenSSL advisory. CWE-825 (Expired Pointer Dereference). |
Why this verdict
- Headline CVE drives the bus: CVE-2026-45447 (CVSS 8.1) is a network-reachable use-after-free with no auth required. The other four CVEs are all OpenSSL-rated LOW with impractical prerequisites (>2 GB inputs, absent CMS fields). The plugin severity must be anchored to the worst CVE.
- MEDIUM label is an artifact of bulletin averaging: The user-reported MEDIUM likely reflects HKCERT's aggregate rating across the full 18-CVE advisory. OpenSSL itself rates CVE-2026-45447 as HIGH. Tenable's VPR of 7.6 (98th percentile) confirms. We upgrade to match the dominant risk.
- Friction: PKCS7_verify() is a narrow attack surface. The TLS stack does not call this function, eliminating the largest class of OpenSSL-consuming applications from the attack path. Only applications that explicitly verify PKCS#7 or S/MIME signatures on untrusted input are reachable. This is a meaningful narrowing from 'all OpenSSL users' but not enough to downgrade below HIGH.
- Friction: AC:H + no weaponized exploit. Heap exploitation across a network boundary requires target-specific heap grooming. No public RCE exploit exists. The crash PoC confirms the bug is real but the RCE path is unproven in the wild. EPSS at 3.57% is elevated but not alarming.
- Role multiplier: OpenSSL is *the* canonical TLS/crypto library — it runs on virtually every Linux server, appliance, and container in the fleet. However, the *specific* attack surface (PKCS7_verify on untrusted input) concentrates risk on: (a) email gateways / MTA plugins processing S/MIME (high-value, network edge — RCE here means mail-tier compromise), (b) PHP applications using
openssl_pkcs7_verify()on user uploads (web-tier compromise), (c) package/artifact verification pipelines using legacy PKCS#7 (supply-chain tier). On a domain controller or hypervisor, PKCS7_verify() is unlikely to be called on untrusted input, so the DC/hypervisor role is not in-scope for this chain. The worst plausible high-value outcome is RCE on an S/MIME-processing email gateway — this is host-level compromise on a network-edge system, justifying a HIGH floor. - EOL amplifier: OpenSSL 1.1.1 has been EOL since September 2023. Running it at all means you're accumulating unpatched CVEs and the fix (1.1.1zh) requires a paid extended support contract. This isn't a CVSS factor but it's an operational severity multiplier that should accelerate your migration timeline.
Why not higher?
CRITICAL would require a reliable, unauthenticated RCE chain with low attack complexity. Here, AC:H is warranted — heap exploitation through a freed BIO vtable requires favorable allocator state that varies by application, libc version, and heap mitigations. No weaponized exploit exists. The attack surface is narrowed to PKCS7_verify() callers processing untrusted input, not all OpenSSL consumers. EPSS at 3.57% is well below the levels seen for actively exploited CVEs.
Why not lower?
The use-after-free is deterministic — the empty digestAlgorithms SET reliably triggers the incorrect BIO free. A crash PoC exists publicly. The CVSS vector is AV:N/PR:N/UI:N, meaning any application exposing PKCS#7 verification to the network is reachable without authentication. S/MIME email gateways are a realistic, high-value target class. Dropping to MEDIUM would ignore the RCE potential on network-edge infrastructure and the EOL status of the library.
What to do — in priority order.
- Audit for PKCS7_verify() callers in your application inventory — The attack surface is limited to applications calling the legacy PKCS#7 API on untrusted data. Run
grep -r 'PKCS7_verify\|openssl_pkcs7_verify' /your/codebaseand check dynamically linked applications withnm -Dorobjdump -Tagainst libssl/libcrypto. Prioritize any hits on internet-facing services (email gateways, web apps). Deploy within 30 days per noisgate mitigation SLA for HIGH. - Migrate off OpenSSL 1.1.1 to a supported branch — OpenSSL 1.1.1 has been EOL since September 2023. The real fix is migrating to 3.4.x LTS, 3.5.x, 3.6.x, or 4.0.x. If you're paying for extended support, apply 1.1.1zh immediately. If you're not paying for extended support, you're not getting patches at all and migration is the only path. Target remediation within 180 days per noisgate remediation SLA for HIGH.
- Block or quarantine malformed S/MIME at the email gateway — If your email infrastructure processes S/MIME, configure your email security gateway (Proofpoint, Mimecast, Microsoft Defender for Office 365) to strip or quarantine S/MIME signed messages with malformed ASN.1 structures. This is a blunt instrument but reduces the primary delivery vector. Deploy within 30 days.
- Enable ASLR and heap hardening on all hosts — Ensure ASLR is enabled (
/proc/sys/kernel/randomize_va_space = 2) and that you're running glibc ≥2.32 with safe-linking enabled. These mitigations don't prevent the use-after-free but significantly raise the bar for achieving controlled code execution from a crash. Verify immediately. - Deploy WAF rules for PKCS#7 content types on web application endpoints — If web applications accept PKCS#7 uploads (content-type
application/pkcs7-mimeorapplication/x-pkcs7-mime), add WAF rules to inspect and rate-limit these uploads. This provides defense-in-depth for the PHPopenssl_pkcs7_verify()attack path.
- Upgrading TLS configuration (cipher suites, protocol versions) — The TLS stack does not call
PKCS7_verify(). TLS hardening is always good practice but does not mitigate this specific vulnerability. - Network segmentation alone — If the vulnerable application is an email gateway, it *must* be network-reachable to function. Segmentation helps contain post-exploitation lateral movement but doesn't prevent the initial exploit.
- Disabling PKCS#7 at the OpenSSL config level — OpenSSL does not provide a configuration knob to disable the PKCS#7 API. The code is compiled in and callable by any linked application. You cannot 'turn off' PKCS7_verify() without recompiling.
Crowdsourced verification payload.
Run this script on each target host as any user with read access to the OpenSSL binary. Invoke with: bash check_cve_2026_45447.sh — no arguments needed. It checks the installed OpenSSL version against the patched release (1.1.1zh). For fleet-wide use, push via Ansible/Salt/SSH and collect exit codes (0 = patched, 1 = vulnerable, 2 = unknown).
#!/usr/bin/env bash
# check_cve_2026_45447.sh
# Checks whether the host is running an OpenSSL 1.1.1 version vulnerable to
# CVE-2026-45447 (Heap Use-After-Free in PKCS7_verify)
# Exit codes: 0 = PATCHED, 1 = VULNERABLE, 2 = UNKNOWN
set -euo pipefail
OPENSSL_BIN="${OPENSSL_BIN:-openssl}"
if ! command -v "$OPENSSL_BIN" &>/dev/null; then
echo "UNKNOWN - openssl binary not found in PATH"
exit 2
fi
VERSION_STRING=$("$OPENSSL_BIN" version 2>/dev/null)
if [[ -z "$VERSION_STRING" ]]; then
echo "UNKNOWN - could not determine OpenSSL version"
exit 2
fi
echo "Detected: $VERSION_STRING"
# Extract major.minor.patch and letter suffix
if [[ "$VERSION_STRING" =~ OpenSSL\ 1\.1\.1([a-z]*) ]]; then
SUFFIX="${BASH_REMATCH[1]}"
# 1.1.1zh is the fixed version. Convert suffix to comparable form.
# Suffixes go: (empty), a, b, ..., z, za, zb, ..., zg, zh
# We need to check if suffix >= 'zh'
if [[ -z "$SUFFIX" ]]; then
echo "VULNERABLE - OpenSSL 1.1.1 (no patch letter) is affected"
exit 1
fi
SUFFIX_LEN=${#SUFFIX}
if [[ $SUFFIX_LEN -eq 1 ]]; then
# Single letter suffix (a-z): all vulnerable
echo "VULNERABLE - OpenSSL 1.1.1${SUFFIX} < 1.1.1zh"
exit 1
elif [[ $SUFFIX_LEN -eq 2 ]]; then
# Double letter suffix (za-zz range)
SECOND_CHAR="${SUFFIX:1:1}"
if [[ "$SECOND_CHAR" < "h" ]]; then
echo "VULNERABLE - OpenSSL 1.1.1${SUFFIX} < 1.1.1zh"
exit 1
else
echo "PATCHED - OpenSSL 1.1.1${SUFFIX} >= 1.1.1zh"
exit 0
fi
elif [[ $SUFFIX_LEN -gt 2 ]]; then
# Suffix longer than 2 chars means newer than zh
echo "PATCHED - OpenSSL 1.1.1${SUFFIX} >= 1.1.1zh"
exit 0
fi
elif [[ "$VERSION_STRING" =~ OpenSSL\ ([0-9]+)\.([0-9]+)\.([0-9]+) ]]; then
MAJOR="${BASH_REMATCH[1]}"
MINOR="${BASH_REMATCH[2]}"
PATCH="${BASH_REMATCH[3]}"
if [[ "$MAJOR" -eq 1 && "$MINOR" -le 0 ]]; then
echo "VULNERABLE - OpenSSL ${MAJOR}.${MINOR}.${PATCH} is EOL and likely affected (check 1.0.2 separately)"
exit 1
elif [[ "$MAJOR" -ge 3 ]]; then
echo "UNKNOWN - OpenSSL ${MAJOR}.${MINOR}.${PATCH} detected; this script checks 1.1.1 branch only. Check CVE-2026-45447 fixes for your branch."
exit 2
fi
else
echo "UNKNOWN - unrecognized OpenSSL version string: $VERSION_STRING"
exit 2
fiWhat defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.