CVE-2026-103399: Libsoup: soupserver: http/1 request smuggling via undrained expect: 100-continue body
A flaw was found in SoupServer (libsoup). When an HTTP/1.x client sends a request with Expect: 100-continue and a request body, and SoupServer returns an early final (non-1xx) response before the body is read, the server neither drains the declared body bytes nor closes the connection. On a keep-alive connection, those leftover bytes are interpreted as a subsequent HTTP request. A remote, unauthenticated attacker can place a complete HTTP request in the body and cause SoupServer to process that smuggled request, leading to unintended request handling.
Other sources
HTTP/1 request-smuggling desync in SoupServer: when a client sends Expect: 100-continue with a Content-Length body and SoupServer emits an early final (non-1xx) response before reading the body (e.g. 401 from SoupAuthDomain, or any handler that sets a final status at the headers stage), libsoup marks the read side DONE without draining the declared body bytes and without sending Connection: close. On a keep-alive connection those leftover body bytes are then parsed as the next HTTP request, so a complete second request placed in the body is smuggled and executed (CWE-444 / RFC 9112 framing violation).
Verified upstream on libsoup 3.7.1 / current HEAD: one crafted connection to an auth-protected path yields 401 then 200, and the smuggled handler runs. Defect location: libsoup/server/http1/soup-server-message-io-http1.c iowrite() STATEHEADERS Expect: 100-continue path (readstate -> DONE without drain/close).
Distinct from CVE-2026-1760 (chunked + keep-alive close) and CVE-2026-1801 (malformed chunk headers). Upstream: https://gitlab.gnome.org/GNOME/libsoup/-/workitems/539. Reporter: Jianqiang (Stark) Li. Embargo: No. Patch discussed upstream; fixed release not yet shipped.
— Red Hat
Libsoup: soupserver: http/1 request smuggling via undrained expect: 100-continue body
— Microsoft
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
debian/libsoup3to a version that resolves this vulnerability.Fixed in 3.8.0-3
Event History
Frequently Asked Questions
Which deployments are exposed to this issue?
Deployments using SoupServer that accept HTTP/1.x keep-alive connections are exposed when a request with Expect: 100-continue can receive an early final, non-1xx response before its declared body is read. Examples include authentication paths returning 401 through SoupAuthDomain and handlers that set a final status while processing headers.
What must an attacker send to exploit the flaw?
An unauthenticated remote attacker needs to send an HTTP/1.x request with Expect: 100-continue and a Content-Length body on a keep-alive connection. The body must contain a complete HTTP request, and the initial request must trigger an early final response before the server consumes that body.
How can I determine whether a request path is affected?
Review SoupServer request paths for cases where the server returns a final non-1xx status at the headers stage without reading the declared request body. In particular, test whether a 401 or other early response to an Expect: 100-continue request leaves the connection open and processes body bytes as a subsequent request.