Version in base suite: 0.090-1 Base version: libhttp-tiny-perl_0.090-1 Target version: libhttp-tiny-perl_0.090-1+deb13u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/libh/libhttp-tiny-perl/libhttp-tiny-perl_0.090-1.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/libh/libhttp-tiny-perl/libhttp-tiny-perl_0.090-1+deb13u1.dsc changelog | 10 patches/CVE-2026-7010-tests.diff | 75 +++++++ patches/CVE-2026-7010.diff | 41 +++ patches/CVE-2026-7017-1.diff | 219 ++++++++++++++++++++ patches/CVE-2026-7017-2.diff | 414 +++++++++++++++++++++++++++++++++++++++ patches/CVE-2026-7017-3.diff | 74 ++++++ patches/CVE-2026-7017-4.diff | 60 +++++ patches/CVE-2026-7017-5.diff | 101 +++++++++ patches/series | 7 9 files changed, 1001 insertions(+) dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpl1jage66/libhttp-tiny-perl_0.090-1.dsc: no acceptable signature found dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpl1jage66/libhttp-tiny-perl_0.090-1+deb13u1.dsc: no acceptable signature found diff -Nru libhttp-tiny-perl-0.090/debian/changelog libhttp-tiny-perl-0.090/debian/changelog --- libhttp-tiny-perl-0.090/debian/changelog 2024-11-15 02:36:25.000000000 +0000 +++ libhttp-tiny-perl-0.090/debian/changelog 2026-08-31 14:34:43.000000000 +0000 @@ -1,3 +1,13 @@ +libhttp-tiny-perl (0.090-1+deb13u1) trixie; urgency=medium + + * [Security] CVE-2026-7010: CRLF-validation in HTTP::Tiny. + (Closes: #1146064) + * [Security] CVE-2026-7017: HTTP::Tiny credential forwarding on + redirects. + (Closes: #1141638) + + -- gregor herrmann Mon, 31 Aug 2026 16:34:43 +0200 + libhttp-tiny-perl (0.090-1) unstable; urgency=medium * Import upstream version 0.090. diff -Nru libhttp-tiny-perl-0.090/debian/patches/CVE-2026-7010-tests.diff libhttp-tiny-perl-0.090/debian/patches/CVE-2026-7010-tests.diff --- libhttp-tiny-perl-0.090/debian/patches/CVE-2026-7010-tests.diff 1970-01-01 00:00:00.000000000 +0000 +++ libhttp-tiny-perl-0.090/debian/patches/CVE-2026-7010-tests.diff 2026-08-31 14:34:43.000000000 +0000 @@ -0,0 +1,75 @@ +From: Stig Palmquist +Date: Mon, 27 Apr 2026 01:09:08 +0200 +Subject: CVE-2026-7010: add tests + +(Backported for Debian by Niko Tyni) + +Origin: backport, https://github.com/Perl-Toolchain-Gang/HTTP-Tiny/commit/207890b6dab21c9db314af50d63202d13f317e2a +Bug: https://github.com/Perl-Toolchain-Gang/HTTP-Tiny/pull/34 +Bug-Debian: https://bugs.debian.org/1146064 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-7010 +--- + t/020_headers.t | 55 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 55 insertions(+) + +--- a/t/020_headers.t ++++ b/t/020_headers.t +@@ -59,3 +59,58 @@ + is_deeply($handle->read_header_lines, $headers, "roundtrip header lines"); + } + ++{ ++ my $fh = tmpfile(); ++ my $handle = HTTP::Tiny::Handle->new(fh => $fh); ++ eval { $handle->write_header_lines({ range => "bytes=13-37${CRLF}X-Injected: foo" }) }; ++ like($@, qr/Invalid HTTP header field value \(Range\)/, ++ "reject CRLF in control field value"); ++} ++ ++{ ++ my $fh = tmpfile(); ++ my $handle = HTTP::Tiny::Handle->new(fh => $fh); ++ eval { $handle->write_header_lines({ "X-Foo-Bar" => "foo${CRLF}X-Injected: foo" }) }; ++ like($@, qr/Invalid HTTP header field value \(X-Foo-Bar\)/, ++ "reject CRLF in other header value"); ++} ++ ++{ ++ my $fh = tmpfile(); ++ my $handle = HTTP::Tiny::Handle->new(fh => $fh); ++ eval { $handle->write_request_header("GET${CRLF}", "/foo", {}, {}) }; ++ like($@, qr/Invalid characters in Method/, ++ "->write_request_header() reject CRLF in method"); ++} ++ ++{ ++ my $fh = tmpfile(); ++ my $handle = HTTP::Tiny::Handle->new(fh => $fh); ++ eval { $handle->write_request_header("GET\x00", "/foo", {}, {}) }; ++ like($@, qr/Invalid characters in Method/, ++ "->write_request_header() reject nullbyte in method"); ++} ++ ++{ ++ my $fh = tmpfile(); ++ my $handle = HTTP::Tiny::Handle->new(fh => $fh); ++ eval { $handle->write_request_header("GET ", "/foo", {}, {}) }; ++ like($@, qr/Invalid characters in Method/, ++ "->write_request_header() reject trailing space in method"); ++} ++ ++{ ++ my $fh = tmpfile(); ++ my $handle = HTTP::Tiny::Handle->new(fh => $fh); ++ eval { $handle->write_request_header("GET", "/foo${CRLF}Foo: 1", {}, {}) }; ++ like($@, qr/Invalid characters in Request-URI/, ++ "->write_request_header() reject CRLF in request-uri"); ++} ++ ++{ ++ my $fh = tmpfile(); ++ my $handle = HTTP::Tiny::Handle->new(fh => $fh); ++ eval { $handle->write_request_header("GET", "/foo bar", {}, {}) }; ++ like($@, qr/Invalid characters in Request-URI/, ++ "->write_request_header() reject space in request-uri"); ++} diff -Nru libhttp-tiny-perl-0.090/debian/patches/CVE-2026-7010.diff libhttp-tiny-perl-0.090/debian/patches/CVE-2026-7010.diff --- libhttp-tiny-perl-0.090/debian/patches/CVE-2026-7010.diff 1970-01-01 00:00:00.000000000 +0000 +++ libhttp-tiny-perl-0.090/debian/patches/CVE-2026-7010.diff 2026-08-31 14:34:43.000000000 +0000 @@ -0,0 +1,41 @@ +From: Stig +Date: Mon, 27 Apr 2026 00:57:48 +0200 +Subject: CVE-2026-7010: fix for request / header smuggling + +Validate control headers, request uri and request method for characters +that could be used in request smuggling or header injection attacks. + +(Backported for Debian by Niko Tyni) + +Origin: backport, https://github.com/Perl-Toolchain-Gang/HTTP-Tiny/commit/d73c7651e82ace02693842df55928b6c3ae7c38d +Bug: https://github.com/Perl-Toolchain-Gang/HTTP-Tiny/pull/34 +Bug-Debian: https://bugs.debian.org/1146064 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-7010 +--- + lib/HTTP/Tiny.pm | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/lib/HTTP/Tiny.pm ++++ b/lib/HTTP/Tiny.pm +@@ -1381,6 +1381,8 @@ + my $field_name = $HeaderCase{$k}; + my $v = $headers->{$k}; + for (ref $v eq 'ARRAY' ? @$v : $v) { ++ die(qq/Invalid HTTP header field value ($field_name): / . $Printable->($_). "\n") ++ unless $_ eq '' || /\A $Field_Content \z/xo; + $_ = '' unless defined $_; + $buf .= "$field_name: $_\x0D\x0A"; + } +@@ -1572,6 +1574,12 @@ + @_ == 5 || die(q/Usage: $handle->write_request_header(method, request_uri, headers, header_case)/ . "\n"); + my ($self, $method, $request_uri, $headers, $header_case) = @_; + ++ die (q/Invalid characters in Request-URI /. $Printable->($request_uri). "\n") ++ if $request_uri =~ /[\x00-\x20\x7F]/; ++ ++ die (q/Invalid characters in Method /. $Printable->($method). "\n") ++ if $method =~ /[\x00-\x20\x7F]/; ++ + return $self->write_header_lines($headers, $header_case, "$method $request_uri HTTP/1.1\x0D\x0A"); + } + diff -Nru libhttp-tiny-perl-0.090/debian/patches/CVE-2026-7017-1.diff libhttp-tiny-perl-0.090/debian/patches/CVE-2026-7017-1.diff --- libhttp-tiny-perl-0.090/debian/patches/CVE-2026-7017-1.diff 1970-01-01 00:00:00.000000000 +0000 +++ libhttp-tiny-perl-0.090/debian/patches/CVE-2026-7017-1.diff 2026-08-31 14:34:43.000000000 +0000 @@ -0,0 +1,219 @@ +From: Olaf Alders +Date: Thu, 14 May 2026 00:13:01 +0000 +Subject: refuse https to http redirects by default + +Allow opt in via allow_downgrade + +(Backported for Debian by Niko Tyni) + +Origin: backport, https://github.com/Perl-Toolchain-Gang/HTTP-Tiny/commit/84984ef3930ddd4afcf5eb83b40d3cee200739c3 +Bug: https://github.com/Perl-Toolchain-Gang/HTTP-Tiny/pull/36 +Bug-Debian: https://bugs.debian.org/1141638 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-7017 +--- + corpus/redirect-11.txt | 21 ++++++++++++++++++++ + corpus/redirect-12.txt | 36 +++++++++++++++++++++++++++++++++++ + corpus/redirect-13.txt | 35 ++++++++++++++++++++++++++++++++++ + corpus/redirect-14.txt | 35 ++++++++++++++++++++++++++++++++++ + lib/HTTP/Tiny.pm | 14 ++++++++++++-- + t/001_api.t | 2 +- + 6 files changed, 140 insertions(+), 3 deletions(-) + create mode 100644 corpus/redirect-11.txt + create mode 100644 corpus/redirect-12.txt + create mode 100644 corpus/redirect-13.txt + create mode 100644 corpus/redirect-14.txt + +--- /dev/null ++++ b/corpus/redirect-11.txt +@@ -0,0 +1,21 @@ ++url ++ https://victim.example/secret ++expected ++ refused-redirect-body ++expected_url ++ https://victim.example/secret ++---------- ++GET /secret HTTP/1.1 ++Host: victim.example ++Connection: close ++User-Agent: HTTP-Tiny/VERSION ++ ++---------- ++HTTP/1.1 302 Found ++Date: Thu, 03 Feb 1994 00:00:00 GMT ++Content-Type: text/plain ++Content-Length: 21 ++Location: http://victim.example/secret ++ ++refused-redirect-body ++ +--- /dev/null ++++ b/corpus/redirect-12.txt +@@ -0,0 +1,36 @@ ++url ++ https://victim.example/secret ++expected ++ success ++expected_url ++ http://victim.example/secret ++new_args ++ allow_downgrade: 1 ++---------- ++GET /secret HTTP/1.1 ++Host: victim.example ++Connection: close ++User-Agent: HTTP-Tiny/VERSION ++ ++---------- ++HTTP/1.1 302 Found ++Date: Thu, 03 Feb 1994 00:00:00 GMT ++Content-Type: text/plain ++Content-Length: 8 ++Location: http://victim.example/secret ++ ++redirect ++ ++---------- ++GET /secret HTTP/1.1 ++Host: victim.example ++Connection: close ++User-Agent: HTTP-Tiny/VERSION ++ ++---------- ++HTTP/1.1 200 OK ++Date: Thu, 03 Feb 1994 00:00:00 GMT ++Content-Type: text/plain ++Content-Length: 7 ++ ++success +--- /dev/null ++++ b/corpus/redirect-13.txt +@@ -0,0 +1,35 @@ ++url ++ https://example.com/index.html ++expected ++ abcdefghijklmnopqrstuvwxyz1234567890abcdef ++expected_url ++ https://example.com/index2.html ++---------- ++GET /index.html HTTP/1.1 ++Host: example.com ++Connection: close ++User-Agent: HTTP-Tiny/VERSION ++ ++---------- ++HTTP/1.1 302 Found ++Date: Thu, 03 Feb 1994 00:00:00 GMT ++Content-Type: text/html ++Content-Length: 53 ++Location: https://example.com/index2.html ++ ++redirect ++ ++---------- ++GET /index2.html HTTP/1.1 ++Host: example.com ++Connection: close ++User-Agent: HTTP-Tiny/VERSION ++ ++---------- ++HTTP/1.1 200 OK ++Date: Thu, 03 Feb 1994 00:00:00 GMT ++Content-Type: text/plain ++Content-Length: 42 ++ ++abcdefghijklmnopqrstuvwxyz1234567890abcdef ++ +--- /dev/null ++++ b/corpus/redirect-14.txt +@@ -0,0 +1,35 @@ ++url ++ http://example.com/index.html ++expected ++ abcdefghijklmnopqrstuvwxyz1234567890abcdef ++expected_url ++ https://example.com/index2.html ++---------- ++GET /index.html HTTP/1.1 ++Host: example.com ++Connection: close ++User-Agent: HTTP-Tiny/VERSION ++ ++---------- ++HTTP/1.1 302 Found ++Date: Thu, 03 Feb 1994 00:00:00 GMT ++Content-Type: text/html ++Content-Length: 53 ++Location: https://example.com/index2.html ++ ++redirect ++ ++---------- ++GET /index2.html HTTP/1.1 ++Host: example.com ++Connection: close ++User-Agent: HTTP-Tiny/VERSION ++ ++---------- ++HTTP/1.1 200 OK ++Date: Thu, 03 Feb 1994 00:00:00 GMT ++Content-Type: text/plain ++Content-Length: 42 ++ ++abcdefghijklmnopqrstuvwxyz1234567890abcdef ++ +--- a/lib/HTTP/Tiny.pm ++++ b/lib/HTTP/Tiny.pm +@@ -18,6 +18,10 @@ + #pod * C — A user-agent string (defaults to 'HTTP-Tiny/$VERSION'). If + #pod C — ends in a space character, the default user-agent string is + #pod appended. ++#pod * C — If a 3xx redirect changes the scheme from C to ++#pod plain C, HTTP::Tiny will by default refuse to follow it, returning the ++#pod 3xx response. Set this to a true value to revert to the legacy behavior of ++#pod redirecting C to C. Default is C. + #pod * C — An instance of L — or equivalent class + #pod that supports the C and C methods + #pod * C — A hashref of default headers to apply to requests +@@ -73,8 +77,8 @@ + my @attributes; + BEGIN { + @attributes = qw( +- cookie_jar default_headers http_proxy https_proxy keep_alive +- local_address max_redirect max_size proxy no_proxy ++ allow_downgrade cookie_jar default_headers http_proxy https_proxy ++ keep_alive local_address max_redirect max_size proxy no_proxy + SSL_options verify_SSL + ); + my %persist_ok = map {; $_ => 1 } qw( +@@ -959,6 +963,11 @@ + my $location = ($headers->{location} =~ /^\//) + ? "$request->{scheme}://$request->{host_port}$headers->{location}" + : $headers->{location} ; ++ my ($to_scheme) = $self->_split_url($location); ++ if (!$self->{allow_downgrade} && $request->{scheme} eq 'https' && $to_scheme eq 'http' ) { ++ return; ++ } ++ + return (($status eq '303' ? 'GET' : $method), $location); + } + return; +@@ -2082,6 +2091,7 @@ + + =for Pod::Coverage SSL_options + agent ++allow_downgrade + cookie_jar + default_headers + http_proxy +--- a/t/001_api.t ++++ b/t/001_api.t +@@ -7,7 +7,7 @@ + use HTTP::Tiny; + + my @accessors = qw( +- agent default_headers http_proxy https_proxy keep_alive local_address ++ agent allow_downgrade default_headers http_proxy https_proxy keep_alive local_address + max_redirect max_size proxy no_proxy timeout SSL_options verify_SSL cookie_jar + ); + my @methods = qw( diff -Nru libhttp-tiny-perl-0.090/debian/patches/CVE-2026-7017-2.diff libhttp-tiny-perl-0.090/debian/patches/CVE-2026-7017-2.diff --- libhttp-tiny-perl-0.090/debian/patches/CVE-2026-7017-2.diff 1970-01-01 00:00:00.000000000 +0000 +++ libhttp-tiny-perl-0.090/debian/patches/CVE-2026-7017-2.diff 2026-08-31 14:34:43.000000000 +0000 @@ -0,0 +1,414 @@ +From: Olaf Alders +Date: Thu, 14 May 2026 17:50:22 +0000 +Subject: strip auth headers on cross-origin redirects + +(Backported for Debian by Niko Tyni) + +Origin: backport, https://github.com/Perl-Toolchain-Gang/HTTP-Tiny/commit/e7a03aedf2395158f2b0d3bad2df943349227bb3 +Bug: https://github.com/Perl-Toolchain-Gang/HTTP-Tiny/pull/36 +Bug-Debian: https://bugs.debian.org/1141638 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-7017 +--- + corpus/redirect-15.txt | 57 +++++++++++++++++++++++++++++++++++ + corpus/redirect-16.txt | 47 +++++++++++++++++++++++++++++ + corpus/redirect-17.txt | 39 ++++++++++++++++++++++++ + corpus/redirect-18.txt | 38 +++++++++++++++++++++++ + corpus/redirect-19.txt | 40 ++++++++++++++++++++++++ + corpus/redirect-20.txt | 41 +++++++++++++++++++++++++ + lib/HTTP/Tiny.pm | 32 ++++++++++++++++---- + t/001_api.t | 5 +-- + 8 files changed, 291 insertions(+), 8 deletions(-) + create mode 100644 corpus/redirect-15.txt + create mode 100644 corpus/redirect-16.txt + create mode 100644 corpus/redirect-17.txt + create mode 100644 corpus/redirect-18.txt + create mode 100644 corpus/redirect-19.txt + create mode 100644 corpus/redirect-20.txt + +--- /dev/null ++++ b/corpus/redirect-15.txt +@@ -0,0 +1,57 @@ ++url ++ http://victim.example/secret ++expected ++ pwned ++expected_url ++ http://victim.example/back ++headers ++ Authorization: Bearer SECRET-TOKEN ++ Cookie: session=SECRET-SESSION ++ Proxy-Authorization: Basic c2VjcmV0OnNlY3JldA== ++---------- ++GET /secret HTTP/1.1 ++Host: victim.example ++Authorization: Bearer SECRET-TOKEN ++Cookie: session=SECRET-SESSION ++Proxy-Authorization: Basic c2VjcmV0OnNlY3JldA== ++Connection: close ++User-Agent: HTTP-Tiny/VERSION ++ ++---------- ++HTTP/1.1 302 Found ++Date: Thu, 03 Feb 1994 00:00:00 GMT ++Content-Type: text/plain ++Content-Length: 8 ++Location: http://attacker.example/loot ++ ++redirect ++ ++---------- ++GET /loot HTTP/1.1 ++Host: attacker.example ++Connection: close ++User-Agent: HTTP-Tiny/VERSION ++ ++---------- ++HTTP/1.1 302 Found ++Date: Thu, 03 Feb 1994 00:00:00 GMT ++Content-Type: text/plain ++Content-Length: 8 ++Location: http://victim.example/back ++ ++redirect ++ ++---------- ++GET /back HTTP/1.1 ++Host: victim.example ++Connection: close ++User-Agent: HTTP-Tiny/VERSION ++ ++---------- ++HTTP/1.1 200 OK ++Date: Thu, 03 Feb 1994 00:00:00 GMT ++Content-Type: text/plain ++Content-Length: 5 ++ ++pwned ++ +--- /dev/null ++++ b/corpus/redirect-16.txt +@@ -0,0 +1,47 @@ ++url ++ http://victim.example/secret ++expected ++ pwned ++expected_url ++ http://attacker.example/loot ++new_args ++ allow_credentialed_redirects: 1 ++headers ++ Authorization: Bearer SECRET-TOKEN ++ Cookie: session=SECRET-SESSION ++ Proxy-Authorization: Basic c2VjcmV0OnNlY3JldA== ++---------- ++GET /secret HTTP/1.1 ++Host: victim.example ++Authorization: Bearer SECRET-TOKEN ++Cookie: session=SECRET-SESSION ++Proxy-Authorization: Basic c2VjcmV0OnNlY3JldA== ++Connection: close ++User-Agent: HTTP-Tiny/VERSION ++ ++---------- ++HTTP/1.1 302 Found ++Date: Thu, 03 Feb 1994 00:00:00 GMT ++Content-Type: text/plain ++Content-Length: 8 ++Location: http://attacker.example/loot ++ ++redirect ++ ++---------- ++GET /loot HTTP/1.1 ++Host: attacker.example ++Authorization: Bearer SECRET-TOKEN ++Cookie: session=SECRET-SESSION ++Proxy-Authorization: Basic c2VjcmV0OnNlY3JldA== ++Connection: close ++User-Agent: HTTP-Tiny/VERSION ++ ++---------- ++HTTP/1.1 200 OK ++Date: Thu, 03 Feb 1994 00:00:00 GMT ++Content-Type: text/plain ++Content-Length: 5 ++ ++pwned ++ +--- /dev/null ++++ b/corpus/redirect-17.txt +@@ -0,0 +1,39 @@ ++url ++ http://example.com/a ++expected ++ ok ++expected_url ++ http://example.com/b ++headers ++ Authorization: Bearer SECRET-TOKEN ++---------- ++GET /a HTTP/1.1 ++Host: example.com ++Authorization: Bearer SECRET-TOKEN ++Connection: close ++User-Agent: HTTP-Tiny/VERSION ++ ++---------- ++HTTP/1.1 302 Found ++Date: Thu, 03 Feb 1994 00:00:00 GMT ++Content-Type: text/plain ++Content-Length: 8 ++Location: http://example.com/b ++ ++redirect ++ ++---------- ++GET /b HTTP/1.1 ++Host: example.com ++Authorization: Bearer SECRET-TOKEN ++Connection: close ++User-Agent: HTTP-Tiny/VERSION ++ ++---------- ++HTTP/1.1 200 OK ++Date: Thu, 03 Feb 1994 00:00:00 GMT ++Content-Type: text/plain ++Content-Length: 2 ++ ++ok ++ +--- /dev/null ++++ b/corpus/redirect-18.txt +@@ -0,0 +1,38 @@ ++url ++ http://example.com:8080/foo ++expected ++ ok ++expected_url ++ http://example.com:8081/bar ++headers ++ Authorization: Bearer SECRET-TOKEN ++---------- ++GET /foo HTTP/1.1 ++Host: example.com:8080 ++Authorization: Bearer SECRET-TOKEN ++Connection: close ++User-Agent: HTTP-Tiny/VERSION ++ ++---------- ++HTTP/1.1 302 Found ++Date: Thu, 03 Feb 1994 00:00:00 GMT ++Content-Type: text/plain ++Content-Length: 8 ++Location: http://example.com:8081/bar ++ ++redirect ++ ++---------- ++GET /bar HTTP/1.1 ++Host: example.com:8081 ++Connection: close ++User-Agent: HTTP-Tiny/VERSION ++ ++---------- ++HTTP/1.1 200 OK ++Date: Thu, 03 Feb 1994 00:00:00 GMT ++Content-Type: text/plain ++Content-Length: 2 ++ ++ok ++ +--- /dev/null ++++ b/corpus/redirect-19.txt +@@ -0,0 +1,40 @@ ++url ++ https://example.com:8443/foo ++expected ++ ok ++expected_url ++ http://example.com:8443/foo ++new_args ++ allow_downgrade: 1 ++headers ++ Authorization: Bearer SECRET-TOKEN ++---------- ++GET /foo HTTP/1.1 ++Host: example.com:8443 ++Authorization: Bearer SECRET-TOKEN ++Connection: close ++User-Agent: HTTP-Tiny/VERSION ++ ++---------- ++HTTP/1.1 302 Found ++Date: Thu, 03 Feb 1994 00:00:00 GMT ++Content-Type: text/plain ++Content-Length: 8 ++Location: http://example.com:8443/foo ++ ++redirect ++ ++---------- ++GET /foo HTTP/1.1 ++Host: example.com:8443 ++Connection: close ++User-Agent: HTTP-Tiny/VERSION ++ ++---------- ++HTTP/1.1 200 OK ++Date: Thu, 03 Feb 1994 00:00:00 GMT ++Content-Type: text/plain ++Content-Length: 2 ++ ++ok ++ +--- /dev/null ++++ b/corpus/redirect-20.txt +@@ -0,0 +1,41 @@ ++url ++ http://victim.example/submit ++method ++ POST ++expected ++ ok ++expected_url ++ http://attacker.example/loot ++headers ++ Authorization: Bearer SECRET-TOKEN ++---------- ++POST /submit HTTP/1.1 ++Host: victim.example ++Authorization: Bearer SECRET-TOKEN ++Connection: close ++Content-Length: 0 ++User-Agent: HTTP-Tiny/VERSION ++ ++---------- ++HTTP/1.1 303 See Other ++Date: Thu, 03 Feb 1994 00:00:00 GMT ++Content-Type: text/plain ++Content-Length: 8 ++Location: http://attacker.example/loot ++ ++redirect ++ ++---------- ++GET /loot HTTP/1.1 ++Host: attacker.example ++Connection: close ++User-Agent: HTTP-Tiny/VERSION ++ ++---------- ++HTTP/1.1 200 OK ++Date: Thu, 03 Feb 1994 00:00:00 GMT ++Content-Type: text/plain ++Content-Length: 2 ++ ++ok ++ +--- a/lib/HTTP/Tiny.pm ++++ b/lib/HTTP/Tiny.pm +@@ -18,6 +18,12 @@ + #pod * C — A user-agent string (defaults to 'HTTP-Tiny/$VERSION'). If + #pod C — ends in a space character, the default user-agent string is + #pod appended. ++#pod * C - If a 3xx redirects to a different scheme, ++#pod host or port, by default HTTP::Tiny will strip away caller-supplied ++#pod C, C and C headers from the ++#pod redirected request and from all subsequent requests in the chain. Set this to a ++#pod true value to revert to the legacy behavior of forwarding those headers. ++#pod Default is C. + #pod * C — If a 3xx redirect changes the scheme from C to + #pod plain C, HTTP::Tiny will by default refuse to follow it, returning the + #pod 3xx response. Set this to a true value to revert to the legacy behavior of +@@ -77,9 +83,9 @@ + my @attributes; + BEGIN { + @attributes = qw( +- allow_downgrade cookie_jar default_headers http_proxy https_proxy +- keep_alive local_address max_redirect max_size proxy no_proxy +- SSL_options verify_SSL ++ allow_credentialed_redirects allow_downgrade cookie_jar default_headers ++ http_proxy https_proxy keep_alive local_address max_redirect max_size ++ proxy no_proxy SSL_options verify_SSL + ); + my %persist_ok = map {; $_ => 1 } qw( + cookie_jar default_headers max_redirect max_size +@@ -453,6 +459,7 @@ + #pod =cut + + my %idempotent = map { $_ => 1 } qw/GET HEAD PUT DELETE OPTIONS TRACE/; ++my %sensitive_headers = map { $_ => 1 } qw/authorization cookie proxy-authorization/; + + sub request { + my ($self, $method, $url, $args) = @_; +@@ -833,6 +840,7 @@ + for ($self->{default_headers}, $args->{headers}) { + next unless defined; + while (my ($k, $v) = each %$_) { ++ next if $args->{_strip_credentials} && exists $sensitive_headers{lc $k}; + $request->{headers}{lc $k} = $v; + $request->{header_case}{lc $k} = $k; + } +@@ -963,10 +971,18 @@ + my $location = ($headers->{location} =~ /^\//) + ? "$request->{scheme}://$request->{host_port}$headers->{location}" + : $headers->{location} ; +- my ($to_scheme) = $self->_split_url($location); ++ my ($to_scheme, $to_host, $to_port) = $self->_split_url($location); + if (!$self->{allow_downgrade} && $request->{scheme} eq 'https' && $to_scheme eq 'http' ) { + return; + } ++ if ( ++ !$self->{allow_credentialed_redirects} ++ && ( $request->{scheme} ne $to_scheme ++ || $request->{host} ne $to_host ++ || $request->{port} ne $to_port ) ++ ) { ++ $args->{_strip_credentials} = 1; ++ } + + return (($status eq '303' ? 'GET' : $method), $location); + } +@@ -1944,8 +1960,7 @@ + how this applies to redirection. + + If the URL includes a "user:password" stanza, they will be used for Basic-style +-authorization headers. (Authorization headers will not be included in a +-redirected request.) For example: ++authorization headers. For example: + + $http->request('GET', 'http://Aladdin:open sesame@example.com/'); + +@@ -1954,6 +1969,10 @@ + + $http->request('GET', 'http://john%40example.com:password@example.com/'); + ++Caller-supplied C, C and C headers ++are stripped on cross-origin redirects. See L's ++C attribute to opt out. ++ + A hashref of options may be appended to modify the request. + + Valid options are: +@@ -2091,6 +2110,7 @@ + + =for Pod::Coverage SSL_options + agent ++allow_credentialed_redirects + allow_downgrade + cookie_jar + default_headers +--- a/t/001_api.t ++++ b/t/001_api.t +@@ -7,8 +7,9 @@ + use HTTP::Tiny; + + my @accessors = qw( +- agent allow_downgrade default_headers http_proxy https_proxy keep_alive local_address +- max_redirect max_size proxy no_proxy timeout SSL_options verify_SSL cookie_jar ++ agent allow_credentialed_redirects allow_downgrade default_headers http_proxy ++ https_proxy keep_alive local_address max_redirect max_size proxy no_proxy timeout ++ SSL_options verify_SSL cookie_jar + ); + my @methods = qw( + new get head put post patch delete post_form request mirror www_form_urlencode can_ssl diff -Nru libhttp-tiny-perl-0.090/debian/patches/CVE-2026-7017-3.diff libhttp-tiny-perl-0.090/debian/patches/CVE-2026-7017-3.diff --- libhttp-tiny-perl-0.090/debian/patches/CVE-2026-7017-3.diff 1970-01-01 00:00:00.000000000 +0000 +++ libhttp-tiny-perl-0.090/debian/patches/CVE-2026-7017-3.diff 2026-08-31 14:34:43.000000000 +0000 @@ -0,0 +1,74 @@ +From: Olaf Alders +Date: Thu, 14 May 2026 20:18:15 +0000 +Subject: Fix protocol-relative Location handling so it can't be used to + bypass credential strip + +(Backported for Debian by Niko Tyni) + +Origin: backport, https://github.com/Perl-Toolchain-Gang/HTTP-Tiny/commit/8f32ca89e21c3ad0422adc698fa6ad17a193f55f +Bug: https://github.com/Perl-Toolchain-Gang/HTTP-Tiny/pull/36 +Bug-Debian: https://bugs.debian.org/1141638 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-7017 +--- + corpus/redirect-21.txt | 38 +++++++++++++++++++++++++++++++++++ + lib/HTTP/Tiny.pm | 6 ++++-- + 2 files changed, 42 insertions(+), 2 deletions(-) + create mode 100644 corpus/redirect-21.txt + +--- /dev/null ++++ b/corpus/redirect-21.txt +@@ -0,0 +1,38 @@ ++url ++ https://victim.example/x ++expected ++ pwned ++expected_url ++ https://attacker.example/loot ++headers ++ Authorization: Bearer TRUSTED-TOKEN ++---------- ++GET /x HTTP/1.1 ++Host: victim.example ++Authorization: Bearer TRUSTED-TOKEN ++Connection: close ++User-Agent: HTTP-Tiny/VERSION ++ ++---------- ++HTTP/1.1 302 Found ++Date: Thu, 03 Feb 1994 00:00:00 GMT ++Content-Type: text/plain ++Content-Length: 8 ++Location: //attacker.example/loot ++ ++redirect ++ ++---------- ++GET /loot HTTP/1.1 ++Host: attacker.example ++Connection: close ++User-Agent: HTTP-Tiny/VERSION ++ ++---------- ++HTTP/1.1 200 OK ++Date: Thu, 03 Feb 1994 00:00:00 GMT ++Content-Type: text/plain ++Content-Length: 5 ++ ++pwned ++ +--- a/lib/HTTP/Tiny.pm ++++ b/lib/HTTP/Tiny.pm +@@ -968,9 +968,11 @@ + and $headers->{location} + and @{$args->{_redirects}} < $self->{max_redirect} + ) { +- my $location = ($headers->{location} =~ /^\//) ++ my $location = $headers->{location} =~ m{^//} ++ ? "$request->{scheme}:$headers->{location}" ++ : $headers->{location} =~ m{^/} + ? "$request->{scheme}://$request->{host_port}$headers->{location}" +- : $headers->{location} ; ++ : $headers->{location}; + my ($to_scheme, $to_host, $to_port) = $self->_split_url($location); + if (!$self->{allow_downgrade} && $request->{scheme} eq 'https' && $to_scheme eq 'http' ) { + return; diff -Nru libhttp-tiny-perl-0.090/debian/patches/CVE-2026-7017-4.diff libhttp-tiny-perl-0.090/debian/patches/CVE-2026-7017-4.diff --- libhttp-tiny-perl-0.090/debian/patches/CVE-2026-7017-4.diff 1970-01-01 00:00:00.000000000 +0000 +++ libhttp-tiny-perl-0.090/debian/patches/CVE-2026-7017-4.diff 2026-08-31 14:34:43.000000000 +0000 @@ -0,0 +1,60 @@ +From: Olaf Alders +Date: Thu, 14 May 2026 20:37:52 +0000 +Subject: demonstrate that https upgrade now strips credentials + +as it is a change of origin + +(Backported for Debian by Niko Tyni) + +Origin: backport, https://github.com/Perl-Toolchain-Gang/HTTP-Tiny/commit/0d7b31e7a16281e918e68fad855ddf249209b026 +Bug: https://github.com/Perl-Toolchain-Gang/HTTP-Tiny/pull/36 +Bug-Debian: https://bugs.debian.org/1141638 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-7017 +--- + corpus/redirect-22.txt | 40 +++++++++++++++++++++++++++++++++++ + 1 file changed, 40 insertions(+) + create mode 100644 corpus/redirect-22.txt + +--- /dev/null ++++ b/corpus/redirect-22.txt +@@ -0,0 +1,40 @@ ++url ++ http://example.com/login ++expected ++ ok ++expected_url ++ https://example.com/login ++headers ++ Authorization: Bearer SECRET-TOKEN ++ Cookie: session=SECRET-SESSION ++---------- ++GET /login HTTP/1.1 ++Host: example.com ++Authorization: Bearer SECRET-TOKEN ++Cookie: session=SECRET-SESSION ++Connection: close ++User-Agent: HTTP-Tiny/VERSION ++ ++---------- ++HTTP/1.1 302 Found ++Date: Thu, 03 Feb 1994 00:00:00 GMT ++Content-Type: text/plain ++Content-Length: 8 ++Location: https://example.com/login ++ ++redirect ++ ++---------- ++GET /login HTTP/1.1 ++Host: example.com ++Connection: close ++User-Agent: HTTP-Tiny/VERSION ++ ++---------- ++HTTP/1.1 200 OK ++Date: Thu, 03 Feb 1994 00:00:00 GMT ++Content-Type: text/plain ++Content-Length: 2 ++ ++ok ++ diff -Nru libhttp-tiny-perl-0.090/debian/patches/CVE-2026-7017-5.diff libhttp-tiny-perl-0.090/debian/patches/CVE-2026-7017-5.diff --- libhttp-tiny-perl-0.090/debian/patches/CVE-2026-7017-5.diff 1970-01-01 00:00:00.000000000 +0000 +++ libhttp-tiny-perl-0.090/debian/patches/CVE-2026-7017-5.diff 2026-08-31 14:34:43.000000000 +0000 @@ -0,0 +1,101 @@ +From: Olaf Alders +Date: Fri, 15 May 2026 20:48:11 +0000 +Subject: Add tests to cover redirects from requests providing basic auth via + the URL + + rather than a manually set Authorization header, with and without the + allow_credentialed_redirects option. + +(Backported for Debian by Niko Tyni) + +Origin: backport, https://github.com/Perl-Toolchain-Gang/HTTP-Tiny/commit/d9aa62b0013abb790b3cf45340320fae475ffdb2 +Bug: https://github.com/Perl-Toolchain-Gang/HTTP-Tiny/pull/36 +Bug-Debian: https://bugs.debian.org/1141638 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-7017 +--- + HTTP-Tiny/corpus/redirect-23.txt | 36 ++++++++++++++++++++++++++++++++++++ + HTTP-Tiny/corpus/redirect-24.txt | 38 ++++++++++++++++++++++++++++++++++++++ + 2 files changed, 74 insertions(+) + create mode 100644 HTTP-Tiny/corpus/redirect-23.txt + create mode 100644 HTTP-Tiny/corpus/redirect-24.txt + +--- /dev/null ++++ b/HTTP-Tiny/corpus/redirect-23.txt +@@ -0,0 +1,36 @@ ++url ++ https://user:pass@victim.example/secret ++expected ++ ok ++expected_url ++ https://attacker.example/loot ++---------- ++GET /secret HTTP/1.1 ++Host: victim.example ++Connection: close ++User-Agent: HTTP-Tiny/VERSION ++Authorization: Basic dXNlcjpwYXNz ++ ++---------- ++HTTP/1.1 302 Found ++Date: Thu, 03 Feb 1994 00:00:00 GMT ++Content-Type: text/plain ++Content-Length: 8 ++Location: https://attacker.example/loot ++ ++redirect ++ ++---------- ++GET /loot HTTP/1.1 ++Host: attacker.example ++Connection: close ++User-Agent: HTTP-Tiny/VERSION ++ ++---------- ++HTTP/1.1 200 OK ++Date: Thu, 03 Feb 1994 00:00:00 GMT ++Content-Type: text/plain ++Content-Length: 2 ++ ++ok ++ +--- /dev/null ++++ b/HTTP-Tiny/corpus/redirect-24.txt +@@ -0,0 +1,38 @@ ++url ++ https://user:pass@victim.example/secret ++expected ++ ok ++expected_url ++ https://attacker.example/loot ++new_args ++ allow_credentialed_redirects: 1 ++---------- ++GET /secret HTTP/1.1 ++Host: victim.example ++Connection: close ++User-Agent: HTTP-Tiny/VERSION ++Authorization: Basic dXNlcjpwYXNz ++ ++---------- ++HTTP/1.1 302 Found ++Date: Thu, 03 Feb 1994 00:00:00 GMT ++Content-Type: text/plain ++Content-Length: 8 ++Location: https://attacker.example/loot ++ ++redirect ++ ++---------- ++GET /loot HTTP/1.1 ++Host: attacker.example ++Connection: close ++User-Agent: HTTP-Tiny/VERSION ++ ++---------- ++HTTP/1.1 200 OK ++Date: Thu, 03 Feb 1994 00:00:00 GMT ++Content-Type: text/plain ++Content-Length: 2 ++ ++ok ++ diff -Nru libhttp-tiny-perl-0.090/debian/patches/series libhttp-tiny-perl-0.090/debian/patches/series --- libhttp-tiny-perl-0.090/debian/patches/series 2024-11-15 02:36:25.000000000 +0000 +++ libhttp-tiny-perl-0.090/debian/patches/series 2026-08-31 14:34:43.000000000 +0000 @@ -1 +1,8 @@ tests-internet.patch +CVE-2026-7010-tests.diff +CVE-2026-7010.diff +CVE-2026-7017-1.diff +CVE-2026-7017-2.diff +CVE-2026-7017-3.diff +CVE-2026-7017-4.diff +CVE-2026-7017-5.diff