Bug 2543949 (CVE-2026-103399)

Summary: CVE-2026-103399 libsoup: SoupServer: HTTP/1 request smuggling via undrained Expect: 100-continue body
Product: [Other] Security Response Reporter: OSIDB Bzimport <bzimport>
Component: vulnerabilityAssignee: Product Security <prodsec-ir-bot>
Status: NEW --- QA Contact:
Severity: medium Docs Contact:
Priority: medium    
Version: unspecifiedCC: rhel-process-autobot, watson-tool-maintainers
Target Milestone: ---Keywords: Security
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: ---
Doc Text:
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.
Story Points: ---
Clone Of: Environment:
Last Closed: Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On: 2543957, 2543958, 2543959    
Bug Blocks:    

Description OSIDB Bzimport 2026-09-30 14:45:41 UTC
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 io_write() STATE_HEADERS Expect: 100-continue path (read_state -> 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/-/work_items/539. Reporter: Jianqiang (Stark) Li. Embargo: No. Patch discussed upstream; fixed release not yet shipped.