← Back to Feed CACHED · 2026-07-01 01:18:42 · CACHE_KEY CVE-2025-32989
CVE-2025-32989 · CWE-295 · Disclosed 2025-07-10

A heap-buffer-overread vulnerability was found in GnuTLS in how it handles the Certificate Transparency

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
Do you agree?
01 · The Real Story

A parser peeks a few bytes past the end of a certificate extension and hands them back to the caller

GnuTLS mishandles the Certificate Transparency Signed Certificate Timestamp (SCT) extension (OID 1.3.6.1.4.1.11129.2.4.2) during X.509 parsing. A malformed SCT length field lets the library read past the allocated buffer, potentially returning adjacent heap bytes to the calling application. Affected versions cover GnuTLS 3.x prior to 3.8.10; the fix landed in 3.8.10 and Red Hat / Ubuntu / Debian have shipped backports for their respective streams.

The vendor called it MEDIUM (5.3) with vector AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N — low confidentiality only, no integrity, no availability. That's honest. The bug is real and network-triggerable, but it is a *bounded* over-read producing a *low-entropy* leak: no session keys, no RCE primitive, no ASLR bypass path published. The rating matches the impact.

"Bounded heap over-read leaks a few bytes during cert parsing — real, but no RCE, no integrity impact, and no in-the-wild interest."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Attacker crafts a certificate with a malformed SCT extension

Using OpenSSL or a custom ASN.1 encoder, the attacker builds an X.509 certificate whose SCT extension declares a length larger than the encoded body. Tools: openssl asn1parse, pyasn1, or a fuzzer harness against libgnutls. The certificate can be self-signed — the parser triggers the flaw before signature validation completes.
Conditions required:
  • ability to present a certificate to a GnuTLS-backed client or server
  • GnuTLS < 3.8.10 in the parsing path
Where this breaks in practice:
  • most TLS clients terminate early on untrusted issuer before deep extension parsing in a way that reaches the caller
  • many stacks strip or ignore the SCT extension unless CT enforcement is on
Detection/coverage: No public Suricata/Snort signatures at time of writing; deep-packet TLS inspectors do not typically inspect SCT length fields.
STEP 02

Attacker delivers the certificate to a GnuTLS peer

Delivery vector is any TLS handshake where the victim parses the cert: reverse-proxied HTTPS to a mail/LDAP/RDP client, an outbound TLS callback from a server-side app (webhook, SMTP-STARTTLS, LDAPS bind), or client-cert auth to a GnuTLS-fronted service. curl --cacert against a hostile server is the trivial PoC harness.
Conditions required:
  • network reachability to the GnuTLS peer
  • peer completes enough of the handshake to parse extensions
Where this breaks in practice:
  • outbound TLS from servers is often restricted by egress policy
  • many callers use OpenSSL not GnuTLS — this only fires where GnuTLS is in the actual parsing path
Detection/coverage: TLS-aware NDR (Zeek, Corelight) can log anomalous cert extensions if a custom script is deployed; no vendor rule ships by default.
STEP 03

Parser reads past the SCT buffer

GnuTLS reads the attacker-declared length instead of clamping to the allocated size, copying adjacent heap bytes into an internal buffer. The exact bytes are non-deterministic and depend on allocator state.
Conditions required:
  • vulnerable GnuTLS build with SCT parsing reachable
Where this breaks in practice:
  • hardened allocators (glibc MALLOC_PERTURB_, jemalloc, or Fedora's _FORTIFY_SOURCE=3) can crash the process instead of returning data
  • ASan/HWASan builds abort immediately
Detection/coverage: Runtime memory-safety instrumentation catches this trivially; production builds do not.
STEP 04

Leaked bytes reach an attacker-observable channel

For a leak to be *useful*, the over-read bytes must flow back to the attacker — typically via an error message, a certificate-info API call surfaced in an HTTP response, or a log entry the attacker can retrieve. If the calling application discards the parsed data, the over-read is functionally a null-op.
Conditions required:
  • calling application echoes parsed cert extension data back over an attacker-observable channel
Where this breaks in practice:
  • the vast majority of GnuTLS callers never surface raw SCT data outward — this is the killer condition
  • even when surfaced, entropy of leaked bytes is low; no known session-key or private-key exposure path
Detection/coverage: Not detectable at the network layer without app-level logging.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo known exploitation. Not on CISA KEV. No public campaigns or IR reports reference this CVE.
Public PoCNo weaponized PoC published. Reproducers exist inside the GnuTLS test suite and Red Hat Bugzilla but require local library linkage, not a drop-in exploit.
EPSS0.01179 (~1.2%) — bottom-decile percentile; FIRST models see effectively zero exploit demand.
KEV statusNot listed. No CISA action required.
CVSS vectorAV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N → network-reachable, no auth, but confidentiality-low only; no integrity or availability impact.
Affected versionsGnuTLS 3.x prior to 3.8.10 across all distros using upstream branch.
Fixed versionsUpstream 3.8.10; RHEL 9 gnutls-3.7.6-x backport, Ubuntu 24.04 3.8.3-1.1ubuntu3.x, Debian bookworm security update — check your distro advisory.
Exposure dataShodan/Censys do not fingerprint GnuTLS version reliably from a handshake; installed base is enormous (default TLS lib on many RHEL/Fedora/embedded builds) but exploit-reachable surface is narrow.
Disclosure date2025-07-10 via Red Hat Bugzilla and coordinated GnuTLS advisory.
ReporterReported to Red Hat Product Security; researcher credit in the GnuTLS NEWS file for 3.8.10.
04 · The Call

noisgate verdict.

Final Verdict
= UNCHANGED to MEDIUM (4.3/10)

The decisive factor is impact scope: this is a bounded heap over-read that yields low-entropy adjacent bytes and requires the calling application to surface parsed SCT data back over an attacker-observable channel — a condition rarely met in production. GnuTLS is ubiquitous, but no plausible chain reaches RCE, key extraction, or authentication bypass, so it stays firmly in MEDIUM.

HIGH impact ceiling (info-disclosure only)
HIGH affected version range
MEDIUM real-world exploitability of the leak-to-observable channel

Why this verdict

  • Impact is capped at low confidentiality. CVSS C:L/I:N/A:N is not vendor sandbagging — the bug reads a bounded number of bytes past a fixed-size buffer with no primitive to pivot to write or execute.
  • No high-value-role multiplier applies. GnuTLS runs inside identity/PKI-adjacent stacks (LDAP, SASL, CUPS, some VPN clients), but *none* of the affected code paths in those roles surface raw parsed SCT data to the network, so the fleet-scale outcome from role (c) still terminates at a bounded byte leak.
  • Exploit demand is near zero. EPSS 0.012, no KEV, no PoC in exploit-DB, no chatter on Trickest/Exploit-DB — attackers are not spending cycles here when they have OpenSSL/NSS memory-safety and Chromium bugs of far higher yield.
  • Delivery has friction. The vulnerable SCT parse only fires when the GnuTLS peer actually processes CT extensions on an attacker-controlled cert AND the caller propagates parsed data outward — a two-hop precondition uncommon in shipping products.

Why not higher?

Upgrading to HIGH would require a plausible chain to RCE, key material extraction, or authentication bypass. None exist: the read is bounded, no allocator-state manipulation primitive is published, and there is no session-key adjacency argument. GnuTLS's role in TLS termination is not enough on its own — the bug must actually leak *secret* bytes, and there is no evidence it reliably does.

Why not lower?

Downgrading to LOW would ignore that GnuTLS is a foundational library shipped in RHEL/Fedora/Debian/Ubuntu base images and embedded firmware, and that the attack is unauthenticated and network-triggerable. Any info-disclosure primitive against a TLS parser deserves a real remediation SLA, even if the current leak is small; parser bugs also tend to cluster, and a follow-on write-primitive discovery would sharply raise the stakes.

05 · Compensating Control

What to do — in priority order.

  1. Patch to GnuTLS 3.8.10 (or your distro's backport) — Vendor patches are shipping across RHEL, Ubuntu, Debian, SUSE. No mitigation SLA applies at MEDIUM — plan patch deployment inside the noisgate remediation SLA of ≤ 365 days, but bundle it into your next monthly OS-package cycle since it is a zero-effort update.
  2. Inventory GnuTLS consumers, not just the library — Enumerate binaries linking libgnutls.so.30 (lsof, ldd, or Snyk/Trivy SBOM scan). Focus especially on outbound TLS clients (CUPS, mailx, socat, wget builds, some VPNs) — those are the paths that touch attacker-controlled certs. Complete inventory within 30 days so your remediation waves are risk-ordered.
  3. Enforce egress TLS to a controlled proxy where feasible — A forward TLS proxy that terminates and re-originates the handshake using OpenSSL or BoringSSL removes GnuTLS from the attacker-cert parsing path for outbound traffic. Applies to the small population of servers making arbitrary outbound TLS calls.
  4. Disable CT enforcement on GnuTLS clients that don't need it — Applications that call gnutls_x509_ext_ct_scts_* explicitly can skip the SCT parse path pending patch. Not universally applicable, and CT verification is desirable — treat as a bridge control, not a target state.
What doesn't work
  • WAF signatures on cert content — the malformed SCT is delivered inside a TLS handshake, before HTTP; the WAF never sees it.
  • Certificate pinning on servers you connect to — pinning validates identity, not extension well-formedness; a pinned cert with a malformed SCT still triggers the parser.
  • Blocking self-signed certs — the flaw is in extension parsing which runs *before* trust decisions; also, a legitimately-issued cert with a corrupt SCT would still hit the code path.
06 · Verification

Crowdsourced verification payload.

Run on each Linux host as root (or any user with read access to /usr/lib*). Invoke as ./check-gnutls-32989.sh. It resolves the linked libgnutls version and compares against the fixed baseline; distro-backported builds are handled by falling back to the package manager version string.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# noisgate verifier — CVE-2025-32989 (GnuTLS SCT heap over-read)
# Exit: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN
set -u

FIXED_UPSTREAM="3.8.10"

verlte() { [ "$1" = "$(printf '%s\n%s\n' "$1" "$2" | sort -V | head -n1)" ]; }
verlt()  { [ "$1" != "$2" ] && verlte "$1" "$2"; }

# 1) Try gnutls-cli
if command -v gnutls-cli >/dev/null 2>&1; then
  V=$(gnutls-cli --version 2>/dev/null | awk '/gnutls-cli/ {print $NF; exit}')
fi

# 2) Fallback: inspect libgnutls SONAME + package db
if [ -z "${V:-}" ]; then
  LIB=$(ldconfig -p 2>/dev/null | awk '/libgnutls\.so\.30/ {print $NF; exit}')
  if [ -n "$LIB" ] && command -v strings >/dev/null 2>&1; then
    V=$(strings "$LIB" | grep -oE '^3\.[0-9]+\.[0-9]+' | head -n1)
  fi
fi

# 3) Package-manager cross-check for distro backports
PKGVER=""
if command -v rpm >/dev/null 2>&1; then
  PKGVER=$(rpm -q --qf '%{VERSION}-%{RELEASE}\n' gnutls 2>/dev/null | head -n1)
elif command -v dpkg-query >/dev/null 2>&1; then
  PKGVER=$(dpkg-query -W -f='${Version}\n' libgnutls30 2>/dev/null | head -n1)
fi

if [ -z "${V:-}" ] && [ -z "$PKGVER" ]; then
  echo "UNKNOWN: GnuTLS not detected"
  exit 2
fi

echo "Detected upstream version: ${V:-n/a}"
echo "Detected package version : ${PKGVER:-n/a}"

# Distro backport heuristic: RHEL/Ubuntu ship fixes without bumping upstream to 3.8.10
if [ -n "$PKGVER" ]; then
  case "$PKGVER" in
    *el9_*|*el8_*|*ubuntu*|*deb12u*|*+deb11u*)
      echo "UNKNOWN: distro backport detected — verify against vendor advisory for ${PKGVER}"
      exit 2 ;;
  esac
fi

if [ -n "${V:-}" ] && verlt "$V" "$FIXED_UPSTREAM"; then
  echo "VULNERABLE: GnuTLS $V < $FIXED_UPSTREAM"
  exit 1
fi

echo "PATCHED: GnuTLS ${V:-$PKGVER} >= $FIXED_UPSTREAM (or vendor-backported)"
exit 0
07 · Bottom Line

If you remember one thing.

TL;DR
This is a real bug but a low-yield one — bounded heap over-read, info-disclosure only, no KEV, EPSS 0.012, no public weaponization. Under the noisgate mitigation SLA for MEDIUM there is *no mitigation deadline* — go straight to the noisgate remediation SLA of ≤ 365 days, but do not sit on it: this is a apt/dnf update away and it is the easiest CVE you will close this quarter. Monday: run the verifier fleet-wide, generate an SBOM-scoped inventory of everything linking libgnutls.so.30, and fold the update into your next monthly patch train (target 30 days). Skip the WAF / cert-pinning theater — those don't help here.

Sources

  1. NVD — CVE-2025-32989
  2. GitHub Advisory GHSA-f7q5-qg45-7vm8
  3. Ubuntu Security Tracker
  4. IBM Security Bulletin — GnuTLS in Storage Defender
  5. IBM Security Bulletin — SAN Volume Controller / Spectrum Virtualize
  6. Cybersecurity-Help GnuTLS bulletin SB20250716122
  7. ThreatINT CVE-2025-32989
  8. Flatcar tracking issue #1810
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.