An attacker mails you an oversized envelope until the mailroom collapses
CVE-2025-32049 is a CWE-770 (Allocation of Resources Without Limits) flaw in SoupWebsocketConnection. When a libsoup-backed WebSocket server (or client) processes a large or heavily fragmented WebSocket message, the library happily allocates memory to buffer it before applying any size cap. A remote, unauthenticated peer can stream multi-gigabyte frames until the process is OOM-killed. Affects libsoup 2.4 and libsoup 3.x across all major distros until patched: Ubuntu fixes land in 2.74.3-6ubuntu1.6, 3.4.4-5ubuntu0.5, 3.6.5-1ubuntu0.2; Red Hat ships errata RHSA-2025:8140/8252/8482/8663/9179; the upstream merge request is GNOME/libsoup!408.
Red Hat and the NVD list this as HIGH (7.5) because the CVSS calculator sees AV:N/AC:L/PR:N/UI:N/A:H and stamps HIGH. That math is correct in the abstract but misleading in practice: this is a pure availability bug, no code execution, no info disclosure, and it only matters on hosts that actually expose a WebSocket endpoint built on libsoup — which is a small slice of the libsoup install base. Most libsoup consumers (GNOME desktop apps, evolution, gnome-online-accounts, geary, librest-driven clients) never run a WebSocket server. Reassessing at MEDIUM reflects the real exposure population, not the calculator output.
4 steps from start to impact.
Locate a libsoup-backed WebSocket endpoint
Upgrade: websocket and fingerprints Server: libsoup or libsoup-derived banners. Targets are typically GNOME-stack web tools, embedded device control planes, or niche WS servers — not mainline NGINX/Node services. Tooling: wscat, httpx, masscan + a custom WS probe.- Reachable TCP port speaking HTTP+WS
- Server upgrades to WebSocket without auth, or attacker has valid creds
- Most enterprise WS endpoints sit behind reverse proxies (NGINX/HAProxy/Envoy) that buffer or enforce
client_max_body_sizeand frame caps before libsoup sees the bytes - Libsoup-as-server is uncommon — the vast majority of libsoup processes are client-side desktop apps
dnf updateinfo/apt list --upgradable will flag the package, but neither identifies which processes actually expose a WS listener — you need runtime asset context.Establish a WebSocket session
websocket-client or autobahn libraries; no exploit kit needed.- Endpoint accepts the Upgrade handshake from attacker's network position
- Origin checks, JWT/cookie auth, or mTLS on the WS path block unauthenticated abuse
- Cloudflare/Akamai WS proxies enforce idle and message-size limits
Stream an oversized or heavily-fragmented message
python -c 'import websocket; ws=websocket.create_connection(url); ws.send(b"A"*(8*1024*1024*1024))'.- Established WS session
- Server process has no external memory cgroup tighter than its working set
- Systemd
MemoryMax=, Kubernetes pod memory limits, or cgroup quotas will OOM-kill the offending worker before host-wide damage - Reverse proxy frame-size limits truncate the message before libsoup buffers it
process_resident_memory_bytes will show it. No CVE-specific signature exists.Process is OOM-killed; service interrupted
- No supervisor auto-restart faster than attacker reconnect interval
- systemd
Restart=always, Kubernetes liveness/restart policies, and HA pairs make the impact a recurring blip rather than a real outage
dmesg/journald; pod restart counter; SLO burn-rate alerts.The supporting signals.
| In-the-wild exploitation | None publicly reported. Not in CISA KEV. No named threat-actor campaigns. |
|---|---|
| Public PoC | Trivial conceptual PoC (oversized WS frame loop); no weaponized exploit in Metasploit/Exploit-DB as of June 2026. Patch discussion in GNOME/libsoup!408. |
| EPSS | 0.00728 (~0.7%, low percentile) — FIRST scores this near the bottom of the exploitability distribution. |
| KEV status | Not listed by CISA. |
| CVSS vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H — network, no auth, no UI, availability-only. No confidentiality or integrity impact. |
| CWE | CWE-770 Allocation of Resources Without Limits or Throttling. |
| Affected versions | libsoup 2.4 and libsoup 3.x through pre-patch releases on all distros. |
| Fixed versions | Ubuntu: libsoup2.4 2.74.3-6ubuntu1.6 / 2.74.3-10ubuntu0.4; libsoup3 3.4.4-5ubuntu0.5 / 3.6.5-1ubuntu0.2. Red Hat: RHSA-2025:8140, 8252, 8482, 8663, 9179, 21657. SUSE/Rocky tracking parallel. |
| Exposure data | Shodan Server: libsoup returns a small set (low thousands) of mostly embedded/IoT and GNOME desktop helper instances — not a hyperscale exposure population. |
| Disclosed | 2025-04-03, reported via Red Hat Product Security (Bugzilla #2357066). |
noisgate verdict.
The decisive factor is availability-only impact with a narrow real exposure population: libsoup is ubiquitous, but libsoup running as a WebSocket *server* on a reachable port is a small slice — most installs are GNOME desktop client code. A successful exploit costs the attacker a process restart, not data and not a foothold.
Why this verdict
- Availability-only bug: CVSS vector explicitly shows C:N/I:N/A:H — no code execution, no info disclosure, no privilege change. The worst-case outcome is process OOM, recoverable in seconds with any supervisor.
- Narrow reachable population: libsoup is installed on virtually every GNOME-based Linux host, but the affected code path requires the process to operate as a WebSocket server or accept WS frames as a client from an attacker-controlled server. The desktop-client majority of installs simply does not expose this surface to the internet.
- Friction stacks compound the downgrade: reverse proxies (NGINX/Envoy/Cloudflare) enforce frame-size and body limits before libsoup; cgroup/Kubernetes memory limits scope the blast to a pod restart; systemd
Restart=alwaysmakes the DoS a blip. - Low exploit interest: EPSS 0.00728, no KEV, no public weaponization, no campaign reporting — attackers prefer L7 floods or HTTP/2 abuses with more leverage.
- Role multiplier — high-value roles: libsoup is NOT canonically the software powering domain controllers, hypervisors, identity providers, PAM, backup, or kernel-mode agents. The bug does not enable lateral movement, credential theft, or supply-chain pivot in any high-value role. The deployment-role floor therefore does not push above MEDIUM.
- Role multiplier — embedded/OT edge case: the one role where this stings harder is embedded device control planes (printers, IoT gateways, kiosks) that ship libsoup-as-server with no proxy and weak supervision. For those, treat as HIGH and patch on the HIGH SLA. For general-purpose servers and workstations, MEDIUM stands.
Why not higher?
HIGH is reserved for vulnerabilities whose realistic exploit outcome includes code execution, credential theft, or fleet-scale availability damage. This bug delivers a recoverable process kill on a narrow subset of hosts, with no integrity or confidentiality impact. The vendor 7.5 is a CVSS-calculator artifact, not a reflection of real-world blast radius.
Why not lower?
LOW would be wrong because the bug is unauthenticated, network-reachable on affected services, and trivially scriptable — embedded/IoT fleets behind no reverse proxy can genuinely be knocked offline by a script kiddie. The compounding factors narrow it but do not erase it.
What to do — in priority order.
- Inventory which hosts actually run libsoup as a WS server — Use
lsof -i -nP | grep -E ':[0-9]+ \(LISTEN\)'cross-referenced withlsof -p $(pgrep -f libsoup) | grep libsoup-, or check service definitions forgnome-online-accounts,evolution-data-server, or any custom apps linkinglibsoup-2.4.so.1/libsoup-3.0.so.0and binding a public port. Patch those first; the desktop majority can ride the standard 365-day MEDIUM remediation window. - Enforce WebSocket frame-size limits at the reverse proxy — On NGINX add
proxy_buffering off; client_max_body_size 1m;on the WS location and considerproxy_request_buffering off;with explicit timeouts. On Envoy setmax_request_bytesand a per-message budget. Apply now — same day for any externally exposed endpoint. - Constrain memory at the process / pod level — Add
MemoryMax=512M(or appropriate) to systemd units backing libsoup-WS servers; set Kubernetes podresources.limits.memory. This bounds the blast to a restart instead of a host kill. Deploy within the noisgate mitigation SLA window. - Require auth on WebSocket Upgrade — Reject Upgrade requests without a valid session cookie / JWT / mTLS at the proxy layer. Eliminates unauthenticated remote DoS.
- Patch libsoup to fixed package version —
dnf upgrade libsoup/apt upgrade libsoup2.4 libsoup-3.0-0to the distro-fixed version (see Intelligence table) within the noisgate remediation SLA (≤365 days for MEDIUM). For embedded/IoT fleets escalate to HIGH SLA (≤180 days).
- EDR / AV signatures — there is no malicious payload to detect; the attack is well-formed WS traffic.
- IP allowlists alone — internal attackers (compromised workstation, malicious tenant) still trigger the bug; allowlists narrow but don't eliminate.
- TLS — TLS doesn't bound message size; the WS message is decrypted into the same buffer.
- Removing libsoup — most GNOME-stack and many distro packages have hard dependencies on libsoup; uninstalling breaks update tooling, online accounts, etc. Patch, don't remove.
Crowdsourced verification payload.
Run on each Linux target host with sudo (needed to read /proc/*/maps). Invoke as sudo bash check-libsoup-32049.sh. Reports PATCHED / VULNERABLE / UNKNOWN based on installed package version AND whether a running process has libsoup mapped.
#!/usr/bin/env bash
# noisgate verification: CVE-2025-32049 libsoup WebSocket DoS
# Exit 0 = PATCHED, 1 = VULNERABLE, 2 = UNKNOWN
set -u
found_pkg=0
vuln_pkg=0
patched_pkg=0
check_deb() {
for p in libsoup2.4-1 libsoup-3.0-0; do
if dpkg -s "$p" >/dev/null 2>&1; then
found_pkg=1
ver=$(dpkg-query -W -f='${Version}' "$p")
echo "[*] $p installed: $ver"
case "$p" in
libsoup2.4-1)
# Ubuntu fixes: 2.74.3-6ubuntu1.6, 2.74.3-10ubuntu0.4
if dpkg --compare-versions "$ver" ge "2.74.3-6ubuntu1.6"; then patched_pkg=1; else vuln_pkg=1; fi ;;
libsoup-3.0-0)
# Ubuntu fixes: 3.4.4-5ubuntu0.5, 3.6.5-1ubuntu0.2, 3.0.7-0ubuntu1
if dpkg --compare-versions "$ver" ge "3.4.4-5ubuntu0.5"; then patched_pkg=1; else vuln_pkg=1; fi ;;
esac
fi
done
}
check_rpm() {
for p in libsoup libsoup3; do
if rpm -q "$p" >/dev/null 2>&1; then
found_pkg=1
ver=$(rpm -q --qf '%{VERSION}-%{RELEASE}\n' "$p")
echo "[*] $p installed: $ver"
# Red Hat patched in RHSA-2025:8140 family. Check via rpm changelog for CVE ref.
if rpm -q --changelog "$p" 2>/dev/null | grep -q 'CVE-2025-32049'; then
patched_pkg=1
else
vuln_pkg=1
fi
fi
done
}
if command -v dpkg >/dev/null 2>&1; then check_deb; fi
if command -v rpm >/dev/null 2>&1; then check_rpm; fi
if [ "$found_pkg" -eq 0 ]; then
echo "UNKNOWN: libsoup not installed via package manager (could be vendored)"
exit 2
fi
# Surface check: any running process mapping libsoup?
exposed=0
if command -v ss >/dev/null 2>&1; then
while read -r pid; do
[ -z "$pid" ] && continue
if grep -q 'libsoup-[23]' "/proc/$pid/maps" 2>/dev/null; then
pname=$(cat "/proc/$pid/comm" 2>/dev/null || echo unknown)
ports=$(ss -tlnp 2>/dev/null | awk -v p="$pid" '$0 ~ "pid="p"," {print $4}' | tr '\n' ' ')
if [ -n "$ports" ]; then
echo "[!] PID $pid ($pname) maps libsoup AND listens on: $ports"
exposed=1
fi
fi
done < <(ls /proc | grep -E '^[0-9]+$')
fi
if [ "$vuln_pkg" -eq 1 ]; then
echo "VULNERABLE: unpatched libsoup present"
[ "$exposed" -eq 1 ] && echo " + exposed listener detected — prioritize"
exit 1
fi
if [ "$patched_pkg" -eq 1 ]; then
echo "PATCHED: libsoup at fixed version"
exit 0
fi
echo "UNKNOWN: could not determine patch state"
exit 2
If you remember one thing.
Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.