Package: release.debian.org
Severity: normal
Tags: trixie
X-Debbugs-Cc: [email protected]
Control: affects -1 + src:libhttp-tiny-perl
User: [email protected]
Usertags: pu

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

I've uploaded libhttp-tiny-perl/0.090-1+deb13u1 to trixie, in the 
hope that in can be included in the upcoming point release.

This upload has been prepared in cooperation with ntyni and carnil 
and is part of the Perl no-DSA security fixes, as decribed in 
#1146369.                                                     

This upload fixes #1146064 aka CVE-2026-7010 and #1141638 aka 
CVE-2026-7017.

All patches are identical (modulo paths and bug numbers) to the ones 
in src:perl (I copied them from there :)) and are taken from upstream 
commits which are already released in newer versions of 
libhttp-tiny-perl.

Changelog entry:

#v+
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 <[email protected]>  Mon, 31 Aug 2026 16:34:43 +0200
#v-

Full debdiff attached.


Thanks in advance,
gregor


-----BEGIN PGP SIGNATURE-----

iQKTBAEBCgB9FiEE0eExbpOnYKgQTYX6uzpoAYZJqgYFAmqXTfpfFIAAAAAALgAo
aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEQx
RTEzMTZFOTNBNzYwQTgxMDREODVGQUJCM0E2ODAxODY0OUFBMDYACgkQuzpoAYZJ
qgbSeRAAuBgoGYymbR0nMbPyutDsE9tCMMmctuFBDawaZiAHIPVfjDFdU+3V6OaF
dh/ykh5Pp0VvRAEnuNu8fgTPoTxTuAgmJNWb2FsrgNZDRYsnI0YaUWueFd3OxKpm
VVUX2HB7HrAWkhE0F+ABaXELuJ0isx/oJ4nND0lhnzVzpN23E5kH3m0g6cWwLBCQ
NLn0WhGUvHpr/pZzwjsVs4kTCPu4DtJJR1b48KJuzD1rrY1yY8bKS9Y+2NakaJZA
OClRJq1Dio+jZXvXQ4GOuddU1dolx0q2ZyFIqCeLEU3UCESn/N5zBHAoqQXXj47M
aMG9+RBQCF3hVvTHJPU8pAP88e2i8eIcUEcrU0pScxK43Rw82eGQnNwzY66TB0cS
mE5kwAFgDIAik58/MzTJKSwb4vbkpSgjtk8VW9u2Q4NG95DHxm3Yi1V/NcBStAkt
TgsjJ4d6GCeVHgcXOkp2Tkz3TX5/jHbVT3lukhzA3WavEeQBbBi0kIFoS27lBQmd
NdO52HOzzTSF5vUFCf5OMnUZKTjXdN85RpSXTAiPp0c2+kzIpyglhoaogQqP+d3M
laYMwLBdO9tMwwLQoXwTsaJflTPNlzrq+0hH+QA6o3zRj4U5v4fNUfYRohB/rzUU
S0aCD3cbPp1LmHZzBNnRJpY57Soq7Aiw8WfKFGstoQVVUFm8Ips=
=Jd2Q
-----END PGP SIGNATURE-----
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 03:36:25.000000000 
+0100
+++ libhttp-tiny-perl-0.090/debian/changelog    2026-08-31 16:34:43.000000000 
+0200
@@ -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 <[email protected]>  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 01:00:00.000000000 +0100
+++ libhttp-tiny-perl-0.090/debian/patches/CVE-2026-7010-tests.diff     
2026-08-31 16:34:43.000000000 +0200
@@ -0,0 +1,75 @@
+From: Stig Palmquist <[email protected]>
+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 
01:00:00.000000000 +0100
+++ libhttp-tiny-perl-0.090/debian/patches/CVE-2026-7010.diff   2026-08-31 
16:34:43.000000000 +0200
@@ -0,0 +1,41 @@
+From: Stig <[email protected]>
+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 
01:00:00.000000000 +0100
+++ libhttp-tiny-perl-0.090/debian/patches/CVE-2026-7017-1.diff 2026-08-31 
16:34:43.000000000 +0200
@@ -0,0 +1,219 @@
+From: Olaf Alders <[email protected]>
+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
++
++<a href="https://example.com/index2.html";>redirect</a>
++
++----------
++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
++
++<a href="https://example.com/index2.html";>redirect</a>
++
++----------
++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<agent> — A user-agent string (defaults to 'HTTP-Tiny/$VERSION'). If
+ #pod   C<agent> — ends in a space character, the default user-agent string is
+ #pod   appended.
++#pod * C<allow_downgrade> — If a 3xx redirect changes the scheme from 
C<https> to
++#pod   plain C<http>, 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<https> to C<http>. Default is C<false>.
+ #pod * C<cookie_jar> — An instance of L<HTTP::CookieJar> — or equivalent class
+ #pod   that supports the C<add> and C<cookie_header> methods
+ #pod * C<default_headers> — 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 
01:00:00.000000000 +0100
+++ libhttp-tiny-perl-0.090/debian/patches/CVE-2026-7017-2.diff 2026-08-31 
16:34:43.000000000 +0200
@@ -0,0 +1,414 @@
+From: Olaf Alders <[email protected]>
+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<agent> — A user-agent string (defaults to 'HTTP-Tiny/$VERSION'). If
+ #pod   C<agent> — ends in a space character, the default user-agent string is
+ #pod   appended.
++#pod * C<allow_credentialed_redirects> - If a 3xx redirects to a different 
scheme,
++#pod   host or port, by default HTTP::Tiny will strip away caller-supplied
++#pod   C<Authorization>, C<Cookie> and C<Proxy-Authorization> 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<false>.
+ #pod * C<allow_downgrade> — If a 3xx redirect changes the scheme from 
C<https> to
+ #pod   plain C<http>, 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 [email protected]/');
+ 
+@@ -1954,6 +1969,10 @@
+ 
+     $http->request('GET', 'http://john%40example.com:[email protected]/');
+ 
++Caller-supplied C<Authorization>, C<Cookie> and C<Proxy-Authorization> headers
++are stripped on cross-origin redirects. See L</new>'s
++C<allow_credentialed_redirects> 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 
01:00:00.000000000 +0100
+++ libhttp-tiny-perl-0.090/debian/patches/CVE-2026-7017-3.diff 2026-08-31 
16:34:43.000000000 +0200
@@ -0,0 +1,74 @@
+From: Olaf Alders <[email protected]>
+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 
01:00:00.000000000 +0100
+++ libhttp-tiny-perl-0.090/debian/patches/CVE-2026-7017-4.diff 2026-08-31 
16:34:43.000000000 +0200
@@ -0,0 +1,60 @@
+From: Olaf Alders <[email protected]>
+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 
01:00:00.000000000 +0100
+++ libhttp-tiny-perl-0.090/debian/patches/CVE-2026-7017-5.diff 2026-08-31 
16:34:43.000000000 +0200
@@ -0,0 +1,101 @@
+From: Olaf Alders <[email protected]>
+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:[email protected]/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:[email protected]/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 
03:36:25.000000000 +0100
+++ libhttp-tiny-perl-0.090/debian/patches/series       2026-08-31 
16:34:43.000000000 +0200
@@ -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

Reply via email to