Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-77680

CVE-2026-77680: libsoup HTTP Range Header DOS Vulnerability

CVE-2026-77680 is a CPU exhaustion flaw in libsoup that allows attackers to cause denial of service through specially crafted HTTP Range headers. This post explains its impact, affected versions, and mitigation steps.

Published:

CVE-2026-77680 Overview

CVE-2026-77680 is an algorithmic complexity vulnerability [CWE-407] in the libsoup HTTP library that persists after the CVE-2025-32907 fix. The flaw resides in the range coalescing loop inside soup_message_headers_get_ranges_internal() in libsoup/soup-message-headers.c. When a client submits an HTTP Range header containing thousands of identical satisfiable ranges, the loop performs O(N²) work while removing merged entries from a GArray. The result is CPU exhaustion that blocks the server event loop. No authentication is required, and the flaw is reachable server-side through handle_partial_get() whenever a SoupServer handler returns HTTP 200 with a non-empty body.

Critical Impact

A single unauthenticated HTTP request with a crafted Range header can consume approximately 90 ms of single-core CPU per request on libsoup HEAD, stalling the server's event loop and enabling denial-of-service against libsoup-based HTTP servers.

Affected Products

  • libsoup versions containing the CVE-2025-32907 fix (commit 9bb92f7a) but not merge request !550
  • Applications embedding vulnerable libsoup as an HTTP server (SoupServer)
  • GNOME and downstream distributions shipping affected libsoup builds

Discovery Timeline

  • 2026-08-20 - Upstream fix merged as libsoup merge request !550
  • 2026-08-25 - CVE-2026-77680 published to NVD
  • 2026-08-26 - Last updated in NVD database

Technical Details for CVE-2026-77680

Vulnerability Analysis

The vulnerability is an algorithmic complexity attack against libsoup's HTTP Range header parser. CVE-2025-32907 previously addressed memory amplification when clients repeated identical ranges. Commit 9bb92f7a corrected merge correctness in soup_message_headers_get_ranges_internal(), but the coalescing loop still removes merged ranges by calling g_array_remove_index() for each coalesced element.

Because GArray stores elements contiguously, every mid-array removal triggers an O(N) memmove. Repeating this removal across N elements yields O(N²) total work. The impact is limited to availability. No memory corruption or information disclosure occurs.

Root Cause

The root cause is inefficient element removal during range coalescing. When many identical satisfiable ranges are supplied, such as bytes=0-0 repeated thousands of times, the loop repeatedly compacts the underlying array element by element instead of performing a single in-place compaction pass. The number of ranges accepted per request is bounded only by the maximum request header size, roughly 100 KiB, allowing approximately 25,000 ranges in a single header.

Attack Vector

An unauthenticated remote attacker sends an HTTP request containing a Range header packed with duplicate satisfiable byte ranges to any endpoint served by a SoupServer handler that returns HTTP 200 with a non-empty body. The vulnerable path is handle_partial_get() in libsoup/server/http1/soup-server-message-io-http1.c. Reporter measurements on libsoup HEAD show approximately 90 ms of single-core CPU consumed per request at the wire maximum. Repeating this request in parallel or serial saturates the server's event loop and prevents legitimate clients from being served.

No verified exploit code is publicly available. See the GNOME libsoup Issue #538 for the upstream report and reproduction details.

Detection Methods for CVE-2026-77680

Indicators of Compromise

  • HTTP requests containing Range headers with hundreds or thousands of comma-separated byte range specifications
  • Repeated identical range tokens such as bytes=0-0,0-0,0-0,... in inbound request logs
  • Sustained high single-core CPU usage on libsoup-based server processes correlated with inbound HTTP traffic
  • Event loop stalls or latency spikes on SoupServer handlers returning HTTP 200 with a body

Detection Strategies

  • Inspect HTTP access logs and reverse proxy telemetry for Range headers exceeding a reasonable count (for example, more than 200 ranges)
  • Deploy web application firewall (WAF) rules that count comma-separated range tokens and block requests exceeding a defined threshold
  • Correlate CPU spikes in libsoup process metrics with concurrent inbound requests to identify potential abuse

Monitoring Recommendations

  • Track per-request processing latency for endpoints served by SoupServer; investigate outliers approaching or exceeding 90 ms
  • Alert on unusual growth in request header size, particularly Range header length approaching the 100 KiB header limit
  • Baseline normal Range request patterns for services that legitimately use HTTP range requests and alert on statistical deviations

How to Mitigate CVE-2026-77680

Immediate Actions Required

  • Upgrade libsoup to a build that includes merge request !550, which replaces per-element removal with O(N) in-place compaction and rejects Range headers requesting more than 200 ranges
  • Apply distribution security updates as they become available; consult the Red Hat CVE-2026-77680 Advisory for RHEL guidance
  • Enforce request rate limiting on unauthenticated endpoints served by libsoup-based applications

Patch Information

The upstream fix is GNOME libsoup Merge Request #550, merged on 2026-08-20. The patch replaces the per-element g_array_remove_index() loop with a single O(N) in-place compaction pass and rejects Range headers containing more than 200 ranges. Downstream advisories are tracked in the Red Hat Bugzilla Report #2520892.

Workarounds

  • Front libsoup-based services with a reverse proxy or WAF that strips or rejects Range headers containing more than a few hundred ranges
  • Reduce the maximum accepted HTTP request header size at the proxy layer to shrink the attack surface below the 100 KiB default
  • Restrict access to unauthenticated SoupServer endpoints through network-level allowlisting where feasible
bash
# Example nginx snippet to bound Range header abuse at a reverse proxy
# Reject requests whose Range header contains more than 200 comma-separated ranges
map $http_range $range_token_count {
    default 0;
    "~^bytes=([^,]*,){200,}" 1;
}

server {
    listen 443 ssl;
    server_name example.local;

    if ($range_token_count) {
        return 400;
    }

    large_client_header_buffers 4 8k;

    location / {
        proxy_pass http://libsoup_backend;
    }
}

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.