Version in base suite: 0.4017-1 Base version: starman_0.4017-1 Target version: starman_0.4018-0+deb13u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/s/starman/starman_0.4017-1.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/s/starman/starman_0.4018-0+deb13u1.dsc Changes | 4 +++ MANIFEST | 1 META.json | 5 ++-- META.yml | 7 +++--- debian/changelog | 10 ++++++++ lib/Starman.pm | 2 - lib/Starman/Server.pm | 28 ++++++++++++------------ script/starman | 42 ++++++++++++++++++------------------ t/te_cl_precedence.t | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 115 insertions(+), 41 deletions(-) dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpzf8mwi_7/starman_0.4017-1.dsc: no acceptable signature found dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpzf8mwi_7/starman_0.4018-0+deb13u1.dsc: no acceptable signature found diff -Nru starman-0.4017/Changes starman-0.4018/Changes --- starman-0.4017/Changes 2023-09-13 20:27:04.000000000 +0000 +++ starman-0.4018/Changes 2026-04-27 19:29:42.000000000 +0000 @@ -1,5 +1,9 @@ Revision history for Perl extension Starman +0.4018 2026-04-27 12:29:41 PDT + - Fix HTTP request smuggling: Transfer-Encoding now takes precedence + over Content-Length per RFC 7230 §3.3.3 (CVE-2026-40560) + 0.4017 2023-09-13 13:27:02 PDT - Handle EINTR when doing sysread calls (Rob Mueller) #148 - Requires perl 5.14 diff -Nru starman-0.4017/MANIFEST starman-0.4018/MANIFEST --- starman-0.4017/MANIFEST 2023-09-13 20:27:04.000000000 +0000 +++ starman-0.4018/MANIFEST 2026-04-27 19:29:42.000000000 +0000 @@ -34,3 +34,4 @@ t/ssl_key.pem t/ssl_largebody.t t/suite.t +t/te_cl_precedence.t diff -Nru starman-0.4017/META.json starman-0.4018/META.json --- starman-0.4017/META.json 2023-09-13 20:27:04.000000000 +0000 +++ starman-0.4018/META.json 2026-04-27 19:29:42.000000000 +0000 @@ -4,7 +4,7 @@ "Tatsuhiko Miyagawa " ], "dynamic_config" : 0, - "generated_by" : "Dist::Milla version v1.0.22, Dist::Zilla version 6.025, CPAN::Meta::Converter version 2.150010", + "generated_by" : "Dist::Milla version v1.0.22, Dist::Zilla version 6.025, CPAN::Meta::Converter version 2.150013", "license" : [ "perl_5" ], @@ -76,7 +76,7 @@ "web" : "https://github.com/miyagawa/Starman" } }, - "version" : "0.4017", + "version" : "0.4018", "x_contributors" : [ "Adam Guthrie ", "Alex Vandiver ", @@ -94,6 +94,7 @@ "John Siracusa ", "Leon Brocard ", "Masahiro Nagano ", + "mauke ", "Olaf Alders ", "Paulo E. Castro ", "Perlover ", diff -Nru starman-0.4017/META.yml starman-0.4018/META.yml --- starman-0.4017/META.yml 2023-09-13 20:27:04.000000000 +0000 +++ starman-0.4018/META.yml 2026-04-27 19:29:42.000000000 +0000 @@ -9,7 +9,7 @@ configure_requires: Module::Build::Tiny: '0.034' dynamic_config: 0 -generated_by: 'Dist::Milla version v1.0.22, Dist::Zilla version 6.025, CPAN::Meta::Converter version 2.150010' +generated_by: 'Dist::Milla version v1.0.22, Dist::Zilla version 6.025, CPAN::Meta::Converter version 2.150013' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html @@ -37,7 +37,7 @@ bugtracker: https://github.com/miyagawa/Starman/issues homepage: https://github.com/miyagawa/Starman repository: https://github.com/miyagawa/Starman.git -version: '0.4017' +version: '0.4018' x_contributors: - 'Adam Guthrie ' - 'Alex Vandiver ' @@ -55,6 +55,7 @@ - 'John Siracusa ' - 'Leon Brocard ' - 'Masahiro Nagano ' + - 'mauke ' - 'Olaf Alders ' - 'Paulo E. Castro ' - 'Perlover ' @@ -70,6 +71,6 @@ - 'Tatsuhiko Miyagawa ' - 'Tim Bunce ' x_generated_by_perl: v5.34.1 -x_serialization_backend: 'YAML::Tiny version 1.73' +x_serialization_backend: 'YAML::Tiny version 1.76' x_spdx_expression: 'Artistic-1.0-Perl OR GPL-1.0-or-later' x_static_install: 1 diff -Nru starman-0.4017/debian/changelog starman-0.4018/debian/changelog --- starman-0.4017/debian/changelog 2023-10-05 21:21:44.000000000 +0000 +++ starman-0.4018/debian/changelog 2026-07-02 10:27:29.000000000 +0000 @@ -1,3 +1,13 @@ +starman (0.4018-0+deb13u1) trixie; urgency=medium + + [ gregor herrmann ] + * Import upstream version 0.4018. + - Fix HTTP request smuggling: Transfer-Encoding now takes precedence + over Content-Length per RFC 7230 §3.3.3 (CVE-2026-40560) + Closes: #1135229 + + -- Salvatore Bonaccorso Thu, 02 Jul 2026 12:27:29 +0200 + starman (0.4017-1) unstable; urgency=medium * Team upload diff -Nru starman-0.4017/lib/Starman/Server.pm starman-0.4018/lib/Starman/Server.pm --- starman-0.4017/lib/Starman/Server.pm 2023-09-13 20:27:04.000000000 +0000 +++ starman-0.4018/lib/Starman/Server.pm 2026-04-27 19:29:42.000000000 +0000 @@ -415,20 +415,7 @@ my $chunked = do { no warnings; lc delete $env->{HTTP_TRANSFER_ENCODING} eq 'chunked' }; - if (my $cl = $env->{CONTENT_LENGTH}) { - my $buf = Plack::TempBuffer->new($cl); - while ($cl > 0) { - my($chunk, $read) = $get_chunk->(); - - if ( !defined $read || $read == 0 ) { - die "Read error: $!\n"; - } - - $cl -= $read; - $buf->print($chunk); - } - $env->{'psgi.input'} = $buf->rewind; - } elsif ($chunked) { + if ($chunked) { my $buf = Plack::TempBuffer->new; my $chunk_buffer = ''; my $length; @@ -460,6 +447,19 @@ $env->{CONTENT_LENGTH} = $length; $env->{'psgi.input'} = $buf->rewind; + } elsif (my $cl = $env->{CONTENT_LENGTH}) { + my $buf = Plack::TempBuffer->new($cl); + while ($cl > 0) { + my($chunk, $read) = $get_chunk->(); + + if ( !defined $read || $read == 0 ) { + die "Read error: $!\n"; + } + + $cl -= $read; + $buf->print($chunk); + } + $env->{'psgi.input'} = $buf->rewind; } else { $env->{'psgi.input'} = $null_io; } diff -Nru starman-0.4017/lib/Starman.pm starman-0.4018/lib/Starman.pm --- starman-0.4017/lib/Starman.pm 2023-09-13 20:27:04.000000000 +0000 +++ starman-0.4018/lib/Starman.pm 2026-04-27 19:29:42.000000000 +0000 @@ -2,7 +2,7 @@ use strict; use 5.008_001; -our $VERSION = '0.4017'; +our $VERSION = '0.4018'; 1; __END__ diff -Nru starman-0.4017/script/starman starman-0.4018/script/starman --- starman-0.4017/script/starman 2023-09-13 20:27:04.000000000 +0000 +++ starman-0.4018/script/starman 2026-04-27 19:29:42.000000000 +0000 @@ -73,7 +73,7 @@ Specifies the address to bind. -This option is for a compatibility with L and you're +This option is for compatibility with L and you're recommended to use C<--listen> instead. =item --port @@ -82,7 +82,7 @@ Specifies the port to bind. -This option is for a compatibility with L and you're +This option is for compatibility with L and you're recommended to use C<--listen> instead. =item -S, --socket @@ -91,12 +91,12 @@ Specifies the path to UNIX domain socket to bind. -This option is for a compatibility with L and you're +This option is for compatibility with L and you're recommended to use C<--listen> instead. =item --workers -Specifies the number of worker pool. Defaults to 5. +Specifies the size of the worker pool. Defaults to 5. Starman by default sets up other spare server configuration based on this workers value, making sure there are B C worker @@ -106,7 +106,7 @@ =item --backlog -Specifies the number of backlog (listen queue size) of listener sockets. Defaults to 1024. +Specifies the backlog size (listen queue size) of listener sockets. Defaults to 1024. On production systems, setting a very low value can allow failover on frontend proxy (like nginx) to happen more quickly, if you have @@ -115,21 +115,21 @@ If you're doing simple benchmarks and getting connection errors, increasing this parameter can help avoid them. You should also consider increasing C. Note that this is not -recommended for real production system if you have another cluster to +recommended for real production systems if you have another cluster to failover (see above). =item --max-requests -Number of the requests to process per one worker process. Defaults to 1000. +Number of requests to process per one worker process. Defaults to 1000. =item --preload-app This option lets Starman preload the specified PSGI application in the master parent process before preforking children. This allows memory savings with copy-on-write memory management. When not set (default), -forked children loads the application in the initialization hook. +forked children load the application in the initialization hook. -Enabling this option can cause bad things happen when resources like +Enabling this option can cause bad things to happen when resources like sockets or database connections are opened at load time by the master process and shared by multiple children. @@ -137,25 +137,25 @@ explicitly set this option to preload the application in the master process. -Alternatively, you can use -M command line option (plackup's common +Alternatively, you can use the C<-M> command line option (plackup's common option) to preload the I rather than the itself. starman -MCatalyst -MDBIx::Class myapp.psgi will load the modules in the master process for memory savings with -CoW, but the actual loading of C is done per children, -allowing resource managements such as database connection safer. +CoW, but the actual loading of C is done per child, +making management of resources such as database connections safer. -If you enable this option, sending C signal to the master process +If you enable this option, sending a C signal to the master process I pick up any code changes you make. See L for details. =item --disable-keepalive -Disable Keep-alive persistent connections. It is an useful workaround +Disable Keep-alive persistent connections. It is a useful workaround if you run Starman behind a broken frontend proxy that tries to pool -connections more than a number of backend workers (i.e. Apache +more connections than there are backend workers (i.e. Apache mpm_prefork + mod_proxy). =item --keepalive-timeout @@ -208,11 +208,11 @@ =item --ssl-cert -Specify the path to SSL certificate file. +Specify the path to the SSL certificate file. =item --ssl-key -Specify the path to SSL key file. +Specify the path to the SSL key file. =item --enable-ssl @@ -226,12 +226,12 @@ =back Starman passes through other options given to L, the -common backend that L uses, so the most options explained in -C such as C<--access-log> or C<--daemonize> works fine in -starman too. +common backend that L uses, so most options explained in +C (such as C<--access-log> or C<--daemonize>) work fine in +starman, too. Setting the environment variable C to 1 makes the -Starman server running in the debug mode. +Starman server run in debug mode. =cut diff -Nru starman-0.4017/t/te_cl_precedence.t starman-0.4018/t/te_cl_precedence.t --- starman-0.4017/t/te_cl_precedence.t 1970-01-01 00:00:00.000000000 +0000 +++ starman-0.4018/t/te_cl_precedence.t 2026-04-27 19:29:42.000000000 +0000 @@ -0,0 +1,57 @@ +use strict; +use warnings; +use Test::TCP; +use IO::Socket::INET qw/ SHUT_WR /; +use HTTP::Response; +use Plack::Loader; +use Test::More; + +# 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 $port = shift; + + my $socket = IO::Socket::INET->new( + PeerAddr => 'localhost', + PeerPort => $port, + Proto => 'tcp', + ) or die "Failed to connect: $!"; + + # Chunked body encodes "Hello World" (0xb = 11 bytes). + # Content-Length: 5 is intentionally wrong — it must be ignored. + my $chunked_body = "b\r\nHello World\r\n0\r\n\r\n"; + my $req = "POST / HTTP/1.1\r\n" + . "Host: localhost\r\n" + . "Transfer-Encoding: chunked\r\n" + . "Content-Length: 5\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 $port = shift; + my $server = Plack::Loader->load('Starman', port => $port, host => '127.0.0.1'); + $server->run(sub { + my $env = shift; + my $body = ''; + $env->{'psgi.input'}->read($body, 8192); + return [ 200, [ 'Content-Type', 'text/plain', 'Content-Length', length($body) ], [ $body ] ]; + }); + }, +); + +done_testing;