# Vulnerability Summary: HTTP Request Smuggling (CVE-2026-48560) ## Overview This vulnerability involves HTTP Request Smuggling. According to RFC 7230 §3.3.3, when both `Transfer-Encoding` and `Content-Length` are present in a request, `Transfer-Encoding` must take precedence over `Content-Length`. Previous code logic allowed attackers to supply malicious requests containing both `Transfer-Encoding: chunked` and `Content-Length`, thereby exploiting front-end reverse proxies to enable HTTP Request Smuggling. ## Impact Scope * **Affected Component**: Starman server module (`lib/Starman/Server.pm`). * **Affected Versions**: 4.6 and earlier. * **Risk**: Attackers may perform HTTP Request Smuggling attacks via the front-end reverse proxy. ## Remediation * **Fixed Version**: 4.6 version. * **Core Change**: Modified the logic in the `prepare_env` function to ensure compliance with RFC 7230 when handling `Transfer-Encoding` and `Content-Length`, i.e., giving priority to `Transfer-Encoding`. ## POC Code ```perl # RFC 7230 §3.3.3: when both Transfer-Encoding and Content-Length are # present, Transfer-Encoding must override Content-Length. #test_tcp: client => sub { my $sport = shift; my $socket = IO::Socket::INET->new( PeerAddr => 'localhost', PeerPort => $sport, Proto => 'tcp', ) or die "Failed to connect: $!"; # Chunked body encodes "Hello World" (0xb = 11 bytes). # Content-Length: 3 is intentionally wrong - it must be ignored. my $chunked_body = "\x0d\x0aHello World\x0d\x0a\x0d\x0a"; my $req = "POST / HTTP/1.1\r\n" . "Host: localhost\r\n" . "Transfer-Encoding: chunked\r\n" . "Content-Length: 3\r\n" . "\r\n" . $chunked_body; $socket->send($req); $socket->shutdown(SHUT_WR); my $response = ''; while (1) { my $n = $socket->sysread($my $buf, 4096); last unless $n; $response .= $buf; } my $res = HTTP::Response->parse($response); is $res->content, 'Hello World', 'Transfer-Encoding: chunked takes precedence over Content-Length'; }, server => sub { my $sport = shift; my $server = Plack::Loader->load('Starman'), port => $sport, host => '127.0.0.1'; $server->run(sub { my $body = ''; $env->{'pgi.input'}->read($body, 8192); return 200, ['Content-Type', 'text/plain'], [$body]; }); }, ```