# 漏洞总结:HTTP 请求走私 (CVE-2026-48560) ## 漏洞概述 该漏洞涉及 HTTP 请求走私(HTTP Request Smuggling)。根据 RFC 7230 §3.3.3,当请求中同时存在 `Transfer-Encoding` 和 `Content-Length` 时,`Transfer-Encoding` 必须覆盖 `Content-Length`。之前的代码逻辑允许攻击者提供包含 `Transfer-Encoding: chunked` 和 `Content-Length` 的恶意请求,从而利用前端反向代理启用 HTTP 请求走私。 ## 影响范围 * **受影响组件**: Starman 服务器模块 (`lib/Starman/Server.pm`)。 * **受影响版本**: 4.6 及更早版本。 * **风险**: 攻击者可能通过前端反向代理实施 HTTP 请求走私攻击。 ## 修复方案 * **修复版本**: 4.6 版本。 * **核心修改**: 修改了 `prepare_env` 函数中的逻辑,确保在处理 `Transfer-Encoding` 和 `Content-Length` 时遵循 RFC 7230 标准,即 `Transfer-Encoding` 优先。 ## POC 代码 ```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]; }); }, ```