This is a giant package jammed into the inspection chute, not a master key to the building
CVE-2023-3446 is an *algorithmic DoS* bug in OpenSSL's DH parameter validation path, not in the normal TLS handshake path. Affected code paths include DH_check(), DH_check_ex(), and EVP_PKEY_param_check() when they are fed attacker-controlled Diffie-Hellman parameters; the openssl dhparam -check and pkeyparam -check CLI paths are also affected. Upstream says vulnerable branches are OpenSSL 3.1.0-3.1.1, 3.0.0-3.0.9, 1.1.1 before 1.1.1v, and 1.0.2 unless a vendor backport or premium-support patch is present.
Most fleet scanners will slap a medium on this because the vulnerable library sits on lots of hosts, but that overstates the real blast radius. OpenSSL explicitly states the SSL/TLS implementation is *not affected*, which kills the common assumption that every HTTPS service using OpenSSL is remotely reachable here. In practice this is a niche exposure that needs a specific application behavior: accepting untrusted DH parameters and calling the vulnerable validation APIs.
4 steps from start to impact.
Find a reachable DH-validation code path
DH_check* or EVP_PKEY_param_check(). The practical weaponized tool is usually just a custom HTTP client, file upload, or API caller; the real primitive is the library call inside the target app, not a standalone exploit framework.- A target application must ingest attacker-controlled DH parameters or DH public-key material
- That application must actually call
DH_check(),DH_check_ex(), orEVP_PKEY_param_check() - The vulnerable OpenSSL build must be present without a distro backport
- Most OpenSSL deployments never expose this API path to untrusted users
- OpenSSL's own advisory says the SSL/TLS implementation is not affected
- Many apps use fixed server-side DH params or never validate attacker-supplied DH params at all
DH_check* path. Reachability needs code review, runtime tracing, or app-owner confirmation.Submit an oversized modulus
p or related parameter set. OpenSSL does realize oversized inputs are invalid, but some checks still continue using the large value, turning validation into a slow CPU path.- Input length must survive transport and parser limits
- The app must pass the parameters onward instead of rejecting them early
- Body-size limits, schema validation, file-size caps, and parser sanity checks often stop this before OpenSSL sees it
- Some applications normalize or constrain crypto parameters before validation
Burn CPU in parameter checks
- The service must allow enough repeated attempts to create contention
- There must be no effective per-request timeout or worker isolation blocking sustained abuse
- Rate limits, queue isolation, cgroup quotas, and autoscaling reduce impact
- Many affected workflows are admin tools, CI tasks, or offline validation jobs rather than public services
Cause availability loss in one app or workflow
- The target service must be important enough that worker starvation matters
- The app must share enough compute with other work to make slowdown operationally visible
- Impact is availability-only
- Single-process or single-workflow failures are easier to absorb than fleet-wide cryptographic compromise
The supporting signals.
| In-the-wild status | No confirmed active exploitation found in the sources reviewed, and it is not listed in CISA KEV. |
|---|---|
| Proof-of-concept availability | No mainstream intrusion-grade public exploit stands out. Upstream says the bug was first found by OSS-Fuzz on 2023-06-25, which strongly suggests reproducer-quality testcases exist, but that is not the same thing as a practical campaign exploit. |
| EPSS | 0.01027 (user-supplied), which is low and consistent with a niche, hard-to-reach availability issue. Percentile was not independently verified from FIRST in this pass. |
| KEV status | Not KEV-listed as of the current CISA KEV catalog. |
| CVSS vector reality check | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L captures that impact is availability-only, but AV:N is misleading in fleet terms because the vulnerable path is *not* the normal TLS surface. |
| Affected versions | Upstream advisory says OpenSSL 3.1, 3.0, 1.1.1, and 1.0.2 are affected; operationally that means 3.1.0-3.1.1, 3.0.0-3.0.9, 1.1.1 before 1.1.1v, and 1.0.2 unless your vendor backported the fix. |
| Fixed versions | Upstream fixes landed in 3.1.2, 3.0.10, and 1.1.1v; 1.0.2 only received a premium-support commit upstream. Distro backports matter: Ubuntu shows fixes such as 3.0.2-0ubuntu1.12 on Jammy and 1.1.1f-1ubuntu2.20 on Focal; RHEL 8 shipped a backport in openssl-1.1.1k-12.el8_9. |
| Scanning / exposure data | There is no meaningful banner-level Internet exposure query for this bug. Because OpenSSL says the SSL/TLS implementation is not affected, Shodan/Censys-style TLS fingerprinting will overcount by equating 'uses OpenSSL' with 'has a reachable DH_check* path'. |
| Disclosure timeline | Disclosed on 2023-07-19; upstream fix commits were published the same day, and the public release train picked them up in 1.1.1v, 3.0.10, and 3.1.2 on 2023-08-01. |
| Reporter / researcher | First detected and auto-reported by OSS-Fuzz; upstream credits the fuzzer addition to Kurt Roeckx and the fix development to Matt Caswell. |
noisgate verdict.
The decisive downgrade factor is that this requires a *reachable application-level DH parameter validation path*, and OpenSSL states the normal SSL/TLS implementation is not affected. That sharply narrows exposed population from 'every box with OpenSSL' to a small subset of custom apps, crypto tooling, and automation workflows.
Why this verdict
- Downward adjustment: the vulnerable path is not TLS — OpenSSL explicitly says the SSL/TLS implementation is not affected, so the usual 'Internet-facing OpenSSL service' assumption does not hold.
- Downward adjustment: attacker needs a very specific app behavior — unauthenticated remote is only possible if the target app accepts attacker-supplied DH parameters and passes them into
DH_check*orEVP_PKEY_param_check(). - Downward adjustment: multiple pre-parser choke points — request-size limits, schema validation, file handling, queue isolation, and worker timeouts often stop or blunt exploitation before it becomes an outage.
- Availability-only impact — there is no code execution, data exposure, or privilege escalation story here; the realistic outcome is CPU burn and service slowdown in one app or job path.
- Threat intel is quiet — no KEV listing, no active exploitation evidence surfaced in this review, and the provided EPSS is low.
Why not higher?
A higher rating would require either broad remote reachability or evidence that standard TLS services are directly exposed, and neither is true here. The need for a niche API usage pattern compounds with the availability-only impact and the absence of active exploitation signals.
Why not lower?
This is still a real denial-of-service bug if you run custom crypto services, certificate tooling, API workflows, or CI jobs that validate untrusted DH parameters. In the wrong internal service, a single reachable validation path can still become an outage trigger, so it is not pure noise.
What to do — in priority order.
- Clamp DH input sizes early — Reject oversized DH parameter blobs before OpenSSL sees them, ideally at the parser or API schema layer. For a LOW verdict there is no formal deadline; do this during normal backlog hygiene if you actually have a reachable DH-validation use case.
- Isolate validation workers — Run crypto-validation tasks with CPU quotas, timeouts, and separate worker pools so a pathological check cannot starve user-facing traffic. For LOW, fold this into normal resilience work rather than emergency change windows.
- Rate-limit the ingestion path — If DH params can arrive over HTTP, message queues, or file upload, cap request frequency and concurrency to prevent cheap repeated submissions from turning slow validation into a service outage. For LOW, apply in ordinary hardening cycles unless you confirm public reachability.
- Identify real reachability before patch panic — Ask app owners and review code for use of
DH_check(),DH_check_ex(),EVP_PKEY_param_check(), ordhparam/pkeyparam -checkin automation. For LOW, this is the right first move because library presence alone massively overstates exposure.
- Tweaking TLS ciphers alone does not solve this, because upstream says the SSL/TLS implementation is not affected.
- A generic WAF is not a universal answer; many affected paths are internal APIs, file-processing jobs, or local CLI automation where HTTP filtering never sees the payload.
- Asset counts based only on 'host has OpenSSL installed' will create false urgency, because most of those hosts do not expose the vulnerable validation path.
Crowdsourced verification payload.
Run this on the target Linux host that has OpenSSL installed. Invoke it as bash check-cve-2023-3446.sh with no arguments; no root is required for basic version checks, though package-manager visibility may be better with elevated privileges on some systems.
#!/usr/bin/env bash
# check-cve-2023-3446.sh
# Purpose: best-effort host check for CVE-2023-3446 (OpenSSL DH_check() excessive CPU / DoS)
# Output: VULNERABLE / PATCHED / UNKNOWN
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN
set -u
have_cmd() { command -v "$1" >/dev/null 2>&1; }
ver_ge() {
# returns 0 if $1 >= $2 using sort -V
[ "$(printf '%s
%s
' "$2" "$1" | sort -V | head -n1)" = "$2" ]
}
ver_lt() {
# returns 0 if $1 < $2
! ver_ge "$1" "$2"
}
note() { printf '%s\n' "$*" >&2; }
# Known upstream fixed versions
FIX_31="3.1.2"
FIX_30="3.0.10"
FIX_111="1.1.1v"
# Known distro backports from public advisories reviewed for this CVE
UBUNTU_JAMMY_FIX="3.0.2-0ubuntu1.12"
UBUNTU_FOCAL_FIX="1.1.1f-1ubuntu2.20"
UBUNTU_LUNAR_FIX="3.0.8-1ubuntu1.4"
RHEL8_FIX="1.1.1k-12.el8_9"
check_upstream_version() {
local raw ver
if ! have_cmd openssl; then
note "openssl binary not found"
return 2
fi
raw="$(openssl version 2>/dev/null || true)"
ver="$(printf '%s' "$raw" | awk '{print $2}')"
if [ -z "$ver" ]; then
note "could not parse openssl version"
return 2
fi
note "Detected openssl binary version: $raw"
case "$ver" in
3.1.*)
if ver_ge "$ver" "$FIX_31"; then return 0; else return 1; fi
;;
3.0.*)
if ver_ge "$ver" "$FIX_30"; then return 0; else return 1; fi
;;
1.1.1*)
if ver_ge "$ver" "$FIX_111"; then return 0; else return 1; fi
;;
1.0.2*)
# upstream public release train did not ship a normal 1.0.2 fixed release
return 1
;;
*)
# Other versions may be vendor forks, LibreSSL, BoringSSL, or unaffected branches
return 2
;;
esac
}
check_dpkg_backport() {
have_cmd dpkg-query || return 2
local pkgver
pkgver="$(dpkg-query -W -f='${Version}' openssl 2>/dev/null || true)"
[ -n "$pkgver" ] || pkgver="$(dpkg-query -W -f='${Version}' libssl3 2>/dev/null || true)"
[ -n "$pkgver" ] || pkgver="$(dpkg-query -W -f='${Version}' libssl1.1 2>/dev/null || true)"
[ -n "$pkgver" ] || return 2
note "Detected dpkg package version: $pkgver"
if printf '%s' "$pkgver" | grep -q 'ubuntu'; then
if printf '%s' "$pkgver" | grep -q '0ubuntu1.12'; then return 0; fi
if printf '%s' "$pkgver" | grep -q '1ubuntu2.20'; then return 0; fi
if printf '%s' "$pkgver" | grep -q '1ubuntu1.4'; then return 0; fi
fi
return 2
}
check_rpm_backport() {
have_cmd rpm || return 2
local pkgver
pkgver="$(rpm -q --qf '%{VERSION}-%{RELEASE}' openssl 2>/dev/null || true)"
[ -n "$pkgver" ] || return 2
note "Detected rpm package version: $pkgver"
case "$pkgver" in
1.1.1k-12.el8_9* ) return 0 ;;
esac
return 2
}
main() {
local upstream_rc dpkg_rc rpm_rc
upstream_rc=2
dpkg_rc=2
rpm_rc=2
check_upstream_version; upstream_rc=$?
check_dpkg_backport; dpkg_rc=$?
check_rpm_backport; rpm_rc=$?
# Any positive distro-backport signal wins
if [ "$dpkg_rc" -eq 0 ] || [ "$rpm_rc" -eq 0 ]; then
echo "PATCHED"
exit 0
fi
# If upstream version is clearly fixed and no distro override contradicts it
if [ "$upstream_rc" -eq 0 ]; then
echo "PATCHED"
exit 0
fi
# If upstream version is clearly in an affected range and we found no backport evidence
if [ "$upstream_rc" -eq 1 ]; then
echo "VULNERABLE"
exit 1
fi
echo "UNKNOWN"
exit 2
}
main
If you remember one thing.
dhparam/pkeyparam -check; if none do, document the rationale and move on. For a LOW verdict there is no noisgate mitigation SLA and no noisgate remediation SLA — treat this as backlog hygiene, patch it in the next normal OpenSSL or distro-library maintenance cycle, and spend scarce patching time on remotely reachable RCEs or KEV-listed issues instead.Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.