A hotel front desk that lets you request the same room key ten thousand times per phone call
libsoup is GNOME's HTTP client/server library. This bug lives in the server-side implementation of HTTP Range requests: a client can stuff a single request with a huge number of overlapping byte ranges, and the server dutifully allocates memory for each one. Result is temporary memory ballooning, not a hard crash. Affected are libsoup 2.x and libsoup3 branches prior to the April 2025 upstream fixes (Red Hat backports landed in RHSA-2025:4439 / RHSA-2025:4508 / RHSA-2025:8128; Debian tracked via bug 1103264).
Vendor score of 5.3 MEDIUM is technically defensible via the CVSS math (AV:N/AC:L/PR:N/UI:N, A:L), but it wildly overstates the operational risk. libsoup in enterprise fleets is overwhelmingly loaded as an HTTP *client* by GNOME desktop applications (Evolution, gnome-online-accounts, Epiphany). The *server* API is used by a small population — mostly Rygel/DLNA media servers, GNOME development test harnesses, and a few embedded appliances. Real-world exposure is minimal.
3 steps from start to impact.
Locate a libsoup-based HTTP server
soup_server_* APIs to serve HTTP — not a client that merely links libsoup. Typical candidates are Rygel (DLNA/UPnP media sharing), some GNOME test/demo servers, or bespoke embedded appliances. Fingerprinting is via Server: header quirks or protocol behavior.- Reachable TCP port hosting a libsoup-server-based HTTP endpoint
- Endpoint that honors
Rangerequests (i.e. serves static or byte-addressable content)
- Enterprise Linux fleets rarely run libsoup as a server; the server API is a niche use case
- Corporate perimeters do not expose DLNA/Rygel — that's a home-LAN protocol
- Most web-facing HTTP in enterprises is nginx/Apache/HAProxy/IIS/envoy, none of which use libsoup
libsoup, libsoup3), not by whether the server API is actually in use — expect false-positive noise on every GNOME workstation.Send a crafted Range request
curl invocation with a Range: bytes=0-1,0-1,0-1,… header containing thousands of overlapping ranges. No public exploit repo needed — one line of shell. The server allocates a buffer per range.- Network path to the port
- Endpoint returns a resource that supports partial content (200/206 with
Accept-Ranges: bytes)
- Any reverse proxy in front (nginx, HAProxy, Cloudflare) will normalize or reject absurd
Rangeheaders before they hit the origin - Request-size limits on load balancers cap the payload
Memory pressure on the host
- Attacker sustains request volume
- Target has no cgroup/systemd memory limit
- systemd unit
MemoryMax=or container cgroup limits contain the blast - OOM killer restarts the service, self-healing
- No RCE, no data disclosure, no integrity impact
The supporting signals.
| In-the-wild exploitation | None observed. Not in CISA KEV. No campaigns tracked by Mandiant, CrowdStrike, or GreyNoise tags. |
|---|---|
| Public PoC | No dedicated exploit repo needed — reproducible with a one-line curl sending a bloated Range header. No Metasploit/Nuclei template as of assessment. |
| EPSS | 0.0057 (~0.57%) — bottom-half percentile; FIRST models don't expect exploitation. |
| CISA KEV | Not listed. |
| CVSS 3.1 vector | AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L → 5.3 MEDIUM. Availability-only, low impact; no C/I. |
| Affected versions | libsoup 2.x and libsoup3 prior to upstream patches merged April 2025. Check distro backports rather than raw upstream numbers. |
| Fixed / backported | RHEL 9: RHSA-2025:4439 & RHSA-2025:4508; RHEL 8: RHSA-2025:8128. Debian bookworm/trixie tracked via bug 1103264. Fedora 40/41 pushed updates April–May 2025. |
| Exposure telemetry | Shodan/Censys do not fingerprint libsoup server distinctly; realistic internet-exposed population is dominated by home Rygel/DLNA on residential IPs, near-zero in enterprise ASN space. |
| Disclosure | 2025-04-14, GNOME project via Red Hat Product Security coordination. |
| Impact ceiling | Memory bloat only. Red Hat notes explicitly: *not* a full DoS. No RCE, no info leak. |
noisgate verdict.
Downgraded one bucket from vendor MEDIUM because the single decisive factor is target-population scarcity: libsoup's server API is used by a tiny fraction (well under 1%) of hosts that install the package — the rest link it purely as an HTTP client, where this bug is unreachable. The impact ceiling is temporary memory pressure with no C/I effect, and any fronting reverse proxy neutralizes the malformed Range header before it lands.
Why this verdict
- Server API is a niche use case: the vast majority of
libsoup-linked processes are GNOME desktop apps acting as HTTP clients; the vulnerablesoup_server_*code path never executes for them. - Impact ceiling is availability-low: Red Hat's own writeup states this is not a full DoS — memory grows during the request and is released after. No RCE, no data disclosure.
- Reverse-proxy termination is the norm: any libsoup server sitting behind nginx, HAProxy, or a cloud LB has the pathological
Rangeheader normalized or rejected upstream. - Role multiplier — desktop / media-share role: the chain succeeds on a Rygel DLNA host or a GNOME test harness; blast radius is *that single process crashing and being restarted by systemd*. No lateral movement, no privilege change.
- Role multiplier — high-value role:
libsoupis not canonically deployed as an identity provider, hypervisor, backup server, CA, kernel-mode agent, network edge appliance, or CI/CD runner. No fleet-scale outcome exists for this component. Floor does not apply. - EPSS 0.0057 + no KEV + no public campaigns: predictive and observed signals both point to non-event.
Why not higher?
MEDIUM would require realistic enterprise-server exposure. Between the vanishing installed base of libsoup-server processes, the availability-only impact, and trivial mitigation via any fronting proxy, there is no operational reason to prioritize this above LOW.
Why not lower?
Not IGNORE because there is a real, remotely reachable code defect with unauthenticated trigger; teams running Rygel, kiosk appliances, or bespoke libsoup-based services genuinely should patch it during normal maintenance windows. Documenting it as backlog hygiene rather than pretending it doesn't exist.
What to do — in priority order.
- Front any libsoup-based HTTP server with a reverse proxy — nginx/HAProxy/Envoy in front of the origin will normalize or drop malformed
Rangeheaders with hundreds of overlapping ranges. Configureclient_header_buffer_sizeand a WAF rule (ModSecurity CRS 920200) to reject Range headers with more than ~10 entries. No mitigation SLA — LOW severity means this rides in the normal 365-day remediation window unless you have a Rygel/DLNA appliance publicly reachable. - Apply cgroup / systemd memory ceilings to libsoup-hosting services — Set
MemoryMax=512M(or lower per role) on the systemd unit, or a container--memorylimit. Bounds the blast so a memory-thrash request kills the process cleanly and lets systemd restart it, instead of pressuring the whole host. - Inventory which hosts actually run libsoup as a *server* — Use
lsof -p <pid> | grep libsouporss -tlnpcorrelated against package-owner queries. Ignore the flood of client-only positives from workstations. Focus remediation on the real server population. - Take the distro backport during the next monthly patch cycle — RHSA-2025:4439 / 4508 / 8128 for RHEL, Debian bookworm-security for Debian. No emergency change window needed — this is normal
dnf update/apt upgradetraffic. noisgate remediation SLA for LOW: no formal deadline, treat as backlog hygiene.
- Blocking
Rangerequests entirely — breaks legitimate resume-download and video-seek behavior; overreacts to a low-severity bug. - EDR / AV signatures — this is a resource-consumption bug in a userland library, not a malware payload; no signature will fire.
- Network segmentation alone — if the vulnerable Rygel/DLNA service is on the segment with any untrusted user, they can still trigger it; segmentation helps but doesn't fix.
Crowdsourced verification payload.
Run on each Linux target as any user (root not required for rpm/dpkg queries). Invoke as ./check-cve-2025-32907.sh. Exits 0 PATCHED, 1 VULNERABLE, 2 UNKNOWN. Also flags whether the host is actually running a libsoup-server process — the only case that operationally matters.
#!/usr/bin/env bash
# check-cve-2025-32907.sh — libsoup Range-header memory DoS
set -u
VULN=0
UNKNOWN=0
FOUND_PKG=0
echo '== libsoup CVE-2025-32907 check =='
# --- Package version check -------------------------------------------------
if command -v rpm >/dev/null 2>&1; then
for pkg in libsoup libsoup3; do
ver=$(rpm -q --qf '%{VERSION}-%{RELEASE}\n' "$pkg" 2>/dev/null | grep -v 'not installed')
[ -z "$ver" ] && continue
FOUND_PKG=1
echo "[pkg] $pkg $ver"
# RHEL backport tags: el9_5, el9_6, el8_10 with post-April-2025 release strings
case "$ver" in
*el9_5*|*el9_6*|*el8_10*|*el10*)
# Trust distro backport tags
echo " -> distro backport tag present, assumed PATCHED" ;;
*)
echo " -> release tag not recognized as post-fix, marking VULNERABLE"
VULN=1 ;;
esac
done
elif command -v dpkg-query >/dev/null 2>&1; then
for pkg in libsoup2.4-1 libsoup-3.0-0; do
ver=$(dpkg-query -W -f='${Version}\n' "$pkg" 2>/dev/null)
[ -z "$ver" ] && continue
FOUND_PKG=1
echo "[pkg] $pkg $ver"
# Debian fixed: libsoup2.4 >= 2.74.3-3+deb12u1 ; libsoup3 >= 3.2.2-2+deb12u1 (approximate)
case "$pkg" in
libsoup2.4-1)
dpkg --compare-versions "$ver" ge '2.74.3-3+deb12u1' || { VULN=1; echo ' -> older than fix, VULNERABLE'; } ;;
libsoup-3.0-0)
dpkg --compare-versions "$ver" ge '3.2.2-2+deb12u1' || { VULN=1; echo ' -> older than fix, VULNERABLE'; } ;;
esac
done
else
echo '[warn] no rpm/dpkg — cannot verify package version'
UNKNOWN=1
fi
if [ $FOUND_PKG -eq 0 ]; then
echo '[info] libsoup not installed — NOT AFFECTED'
exit 0
fi
# --- Server-role check (the only case that actually matters) --------------
echo '== libsoup server-role check =='
SERVERS=0
if command -v lsof >/dev/null 2>&1; then
while read -r pid; do
[ -z "$pid" ] && continue
if lsof -p "$pid" 2>/dev/null | grep -q libsoup; then
# Listening sockets on this pid?
if ss -tlnp 2>/dev/null | grep -q "pid=$pid,"; then
cmd=$(ps -p "$pid" -o comm= 2>/dev/null)
echo " [!] pid=$pid ($cmd) linked to libsoup AND listening — HIGH-RELEVANCE target"
SERVERS=$((SERVERS+1))
fi
fi
done < <(pgrep -a . 2>/dev/null | awk '{print $1}')
fi
[ $SERVERS -eq 0 ] && echo ' no libsoup-linked listening processes found (client-only exposure)'
# --- Verdict ---------------------------------------------------------------
if [ $VULN -eq 1 ]; then
if [ $SERVERS -gt 0 ]; then
echo 'RESULT: VULNERABLE (and running as server — patch)'
else
echo 'RESULT: VULNERABLE (client-only linkage — low operational risk)'
fi
exit 1
fi
if [ $UNKNOWN -eq 1 ]; then echo 'RESULT: UNKNOWN'; exit 2; fi
echo 'RESULT: PATCHED'
exit 0
If you remember one thing.
dnf update / apt upgrade cycle. The one thing worth doing Monday morning is a five-minute inventory: run the verification script fleet-wide and identify any host that is actually running libsoup as an HTTP server (Rygel/DLNA appliances, embedded kiosks, GNOME dev boxes with test harnesses exposed). If any of those are reachable from an untrusted network, either put them behind an nginx reverse proxy with a Range-header sanity rule this week, or patch them out-of-band. Everything else — every workstation, every GNOME desktop, every server that merely happens to have libsoup installed as a client dependency — closes out as backlog hygiene.Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.