A parser that reads one byte past the fence while sniffing whether a blob is RSS or HTML
CVE-2025-32053 is a heap buffer over-read in libsoup's content-sniffing path — specifically the sniff_feed_or_html() and skip_insignificant_space() helpers used to guess whether an HTTP payload is a feed or an HTML document. When an attacker-controlled response body is truncated or malformed at just the right byte, the sniffer walks past the end of the allocated buffer. Affected builds include libsoup2.4 up through the pre-patch 2.74.x line and libsoup3 up to 3.6.x; distro fixes landed as 2.74.3-6ubuntu1.2 / 2.74.2-3ubuntu0.2 / 2.70.0-1ubuntu0.2 for libsoup2.4 and 3.4.4-5ubuntu0.2 / 3.6.0-2ubuntu0.2 for libsoup3, plus Red Hat's RHSA-2025:4508 and SUSE backports.
Red Hat and NVD both scored this 6.5 MEDIUM with AV:N/AC:L/PR:N/UI:N/C:L/I:N/A:L. That vector overstates the real risk for two reasons: (1) the primitive is a bounded read, not a write, so it cannot corrupt control flow — the worst plausible outcome is a small leak of adjacent heap bytes or a SIGSEGV in the consuming process; (2) libsoup is primarily a client-side HTTP library (used by GNOME apps, Evolution, epiphany, package tooling, and some server-side scrapers), so exploitation requires the victim to fetch attacker-controlled content, not the attacker to reach a listening port. The vendor label is defensible on paper but the exploitable population is small — this is LOW in operational reality.
3 steps from start to impact.
Attacker stages a malformed HTTP response
http.server or mitmproxy script can produce the byte pattern.- Attacker can serve HTTP content the victim will fetch
- Victim application uses libsoup for the fetch
- Server-side libsoup deployments (rare) will not fetch attacker content by default
Victim libsoup client fetches and sniffs the body
soup_content_sniffer_sniff to guess MIME type. sniff_feed_or_html() then calls skip_insignificant_space(), which reads past the end of the heap allocation.- libsoup version pre-2.74.3 / pre-3.6.1 in use
- Content sniffing enabled (default for many consumers)
- Non-GNOME Linux fleets and hardened server images rarely link libsoup
- WebKitGTK sandboxing contains the process even if it crashes
SIGSEGV in libsoup-3.0.Heap adjacency determines outcome
- Adjacent heap page unmapped (for DoS) or attacker has a side-channel to observe sniffed bytes
- glibc
MALLOC_PERTURB_and hardened_malloc reduce leak utility - No known exploit that turns this into RCE
libsoup symbol range; no signature in EDR.The supporting signals.
| In-the-wild exploitation | None observed. No public campaign, no honeypot hits, no vendor IOC. |
|---|---|
| KEV status | Not listed by CISA as of 2026-07-01. |
| EPSS | 0.0057 (~0.57%) — bottom quartile of exploitability probability. |
| Public PoC | No weaponized PoC. GNOME GitLab issue and Red Hat Bugzilla contain reproducer bytes; no Metasploit/Nuclei module. |
| CVSS vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:L — network reach + low-conf + low-avail; no integrity, no write primitive. |
| CWE | CWE-126 Buffer Over-read (read-only, no control-flow corruption). |
| Affected versions | libsoup2.4 ≤ 2.74.2, libsoup3 ≤ 3.6.0 across major distros. |
| Fixed versions | Ubuntu: libsoup2.4 2.74.3-6ubuntu1.2/2.74.2-3ubuntu0.2/2.70.0-1ubuntu0.2; libsoup3 3.4.4-5ubuntu0.2/3.6.0-2ubuntu0.2. RHEL: RHSA-2025:4508. SUSE and Debian backports available. |
| Disclosure | 2025-04-03, credited via GNOME/Red Hat coordinated disclosure. |
| Exposure telemetry | GreyNoise/Shodan not meaningful (client-side library, not a listening service). |
noisgate verdict.
The single decisive factor is the primitive class: this is a bounded heap over-read in a content-sniffing helper, not a write, not a control-flow bug, and libsoup is overwhelmingly a client-side library — the affected population is desktop GNOME endpoints and a handful of scrapers, not internet-exposed servers. Vendor CVSS 6.5 assumes network reachability that overstates practical impact.
Why this verdict
- Read-only primitive: CWE-126 is a bounded over-read; there is no write, no heap corruption, no control-flow hijack path. Confidentiality impact is small heap-adjacency bytes, not credentials or session material.
- Client-side library posture: libsoup lives inside GNOME desktop apps and a few scripted HTTP clients — not on internet-listening sockets. The
AV:Nin the CVSS vector counts any 'attacker serves a response' as network, which is technically correct but operationally means 'user must fetch attacker content'. - No weaponization signal: EPSS 0.57%, no KEV, no public exploit, no telemetry from GreyNoise/Shodan (nothing to scan for). Nine months post-disclosure with zero campaign activity is a strong negative signal.
- Role multiplier — desktop GNOME endpoint: chain succeeds as a process crash or tiny heap-byte leak inside a sandboxed browser/mail client. Blast radius is one user session, contained by WebKitGTK / bubblewrap / Flatpak sandbox.
- Role multiplier — server-side scraper / feed reader: chain succeeds as a crash of the fetcher process. Blast radius is service restart. No pivot to host, no lateral movement primitive.
- Role multiplier — high-value roles: libsoup is not canonically deployed on DCs, hypervisors, IdPs, PAM, backup, CA, or kernel-mode agents. The high-value-role floor does not engage — there is no realistic deployment where this bug ends in domain/fleet/tenant compromise.
Why not higher?
MEDIUM would require either a plausible RCE path (there is none — this is a read, not a write) or evidence of exploitation (there is none). The vendor's 6.5 leans on AV:N and C:L, but nothing in the disclosed detail supports meaningful data theft; adjacent-heap bytes in a sniffer helper are not high-value memory.
Why not lower?
IGNORE is inappropriate because the code *is* reachable from attacker-controlled content on a widely deployed Linux desktop library, and any defender with GNOME endpoints should still ship the patch through normal channels. It is a real bug, just not an urgent one.
What to do — in priority order.
- Roll libsoup patches through standard OS update cycles — RHEL 8/9, Ubuntu 20.04/22.04/24.04, SUSE, and Debian all shipped fixes in Q2 2025. LOW severity → no noisgate mitigation SLA; ship on the standard ≤365-day remediation window and prioritize below any HIGH/CRITICAL backlog.
- Disable content sniffing in libsoup-consuming apps where feasible — Applications can call
soup_session_remove_feature_by_type(session, SOUP_TYPE_CONTENT_SNIFFER)to bypass the vulnerable code path entirely. Useful for internal scrapers/feed pollers you control; not applicable to third-party GUI apps. - Confirm desktop app sandboxing is in place — Flatpak (bubblewrap) and Snap confinement contain the crash blast radius. Verify Evolution, Epiphany, and RSS readers on user endpoints are running under
flatpakor the distro's default AppArmor/SELinux profile — this is baseline hygiene, not new work. - Enable systemd-coredump/ABRT reporting — If a user does hit the crash, you want the coredump to reach central telemetry so you can distinguish this bug from other libsoup issues. Configure now, review over the 365-day window.
- Perimeter WAF rules — the vulnerable code runs on the client side after fetching the response; nothing at your ingress inspects an outbound response body arriving at a GNOME desktop.
- Network segmentation of servers — libsoup is a client library; segmenting your server VLANs does not reduce exposure on user workstations.
- EDR memory-scanning signatures — no exploit exists to signature, and the over-read produces no consistent detonation artifact.
- MFA / auth hardening — the bug is pre-auth by design; user authentication has no bearing on content sniffing.
Crowdsourced verification payload.
Run on any Linux host to check the installed libsoup version against the distro-patched baselines. Requires no privileges. Invoke as bash check-cve-2025-32053.sh; exits 0 PATCHED, 1 VULNERABLE, 2 UNKNOWN.
#!/usr/bin/env bash
# noisgate check: CVE-2025-32053 libsoup heap over-read
# Prints VULNERABLE / PATCHED / UNKNOWN and exits 1/0/2
set -u
found_any=0
vuln=0
unknown=0
check_deb() {
# $1 = package name, $2 = fixed version threshold
local pkg="$1" fixed="$2"
local installed
installed=$(dpkg-query -W -f='${Version}\n' "$pkg" 2>/dev/null || true)
[ -z "$installed" ] && return
found_any=1
if dpkg --compare-versions "$installed" ge "$fixed"; then
echo "[OK] $pkg $installed >= $fixed"
else
echo "[BAD] $pkg $installed < $fixed"
vuln=1
fi
}
check_rpm() {
local pkg="$1" fixed="$2"
local installed
installed=$(rpm -q --qf '%{VERSION}-%{RELEASE}\n' "$pkg" 2>/dev/null | head -n1)
[ -z "$installed" ] || echo "$installed" | grep -q 'not installed' && return
found_any=1
# rpmdev-vercmp returns 11 if a<b, 12 if a>b, 0 if equal
if rpmdev-vercmp "$installed" "$fixed" >/dev/null 2>&1; then
rc=$?
else
rc=$?
fi
case $rc in
0|12) echo "[OK] $pkg $installed >= $fixed" ;;
11) echo "[BAD] $pkg $installed < $fixed"; vuln=1 ;;
*) echo "[???] $pkg $installed (cmp failed vs $fixed)"; unknown=1 ;;
esac
}
if command -v dpkg-query >/dev/null 2>&1; then
. /etc/os-release 2>/dev/null || true
case "${VERSION_ID:-}" in
20.04) check_deb libsoup2.4-1 2.70.0-1ubuntu0.2 ;;
22.04) check_deb libsoup2.4-1 2.74.2-3ubuntu0.2 ;;
24.04) check_deb libsoup2.4-1 2.74.3-6ubuntu1.2
check_deb libsoup-3.0-0 3.4.4-5ubuntu0.2 ;;
24.10) check_deb libsoup-3.0-0 3.6.0-2ubuntu0.2 ;;
*) check_deb libsoup2.4-1 2.74.3
check_deb libsoup-3.0-0 3.6.1 ;;
esac
elif command -v rpm >/dev/null 2>&1; then
# RHSA-2025:4508 shipped fixed builds; check both series
check_rpm libsoup 2.62.3-3.el8_10.1
check_rpm libsoup 2.72.0-8.el9_4.1
check_rpm libsoup3 3.4.4-1.el9_4.1
fi
if [ "$found_any" -eq 0 ]; then
echo "UNKNOWN: libsoup not installed on this host"
exit 2
fi
if [ "$vuln" -eq 1 ]; then
echo "VULNERABLE"
exit 1
fi
if [ "$unknown" -eq 1 ]; then
echo "UNKNOWN"
exit 2
fi
echo "PATCHED"
exit 0
If you remember one thing.
apt/dnf update cycle in one cycle and you can close the ticket. Monday morning: confirm your standard patching pipeline covers RHEL 8/9, Ubuntu 20.04/22.04/24.04, and SUSE libsoup packages, spot-check ten GNOME desktops with the verification script, and move on to your KEV backlog — do not let a vendor 6.5 pull attention off active-exploitation work.Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.