Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions debian/changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
libwww-perl (6.58-1deepin1) unstable; urgency=medium

* Add fix for CVE-2026-8368 (credential leakage via cross-origin
redirects)

-- deepin-ci-robot <packages@deepin.org> Thu, 04 Jun 2026 09:54:32 +0800

libwww-perl (6.58-1) unstable; urgency=medium

* Import upstream version 6.58.
Expand Down
152 changes: 152 additions & 0 deletions debian/patches/CVE-2026-8368.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
Description: Strip Authorization and Proxy-Authorization on cross-origin redirect
Prevent credential leakage by stripping Authorization and Proxy-Authorization
headers when following cross-origin 3xx redirects (different scheme, host, or
port). Also refuse https->http downgrade redirects by default.
.
Same defect class as libcurl CVE-2018-1000007, Python requests CVE-2018-18074,
wget CVE-2021-31879, and Go net/http CVE-2024-45336.
.
LWP::UserAgent (libwww-perl)
.
CVE-2026-8368
Author: Olaf Alders <olaf@wundersolutions.com>
Origin: upstream, https://github.com/libwww-perl/libwww-perl/commit/9c4aeb6
Origin: upstream, https://github.com/libwww-perl/libwww-perl/commit/792a5dc
Bug: https://github.com/libwww-perl/libwww-perl/issues
Forwarded: not-needed
Last-Update: 2026-06-04

Index: libwww-perl/lib/LWP/UserAgent.pm
===================================================================
--- libwww-perl.orig/lib/LWP/UserAgent.pm
+++ libwww-perl/lib/LWP/UserAgent.pm
@@ -85,6 +85,9 @@ sub new
$requests_redirectable = ['GET', 'HEAD']
unless defined $requests_redirectable;

+ my $allow_credentialed_redirects = delete $cnf{allow_credentialed_redirects};
+ my $allow_downgrade = delete $cnf{allow_downgrade};
+
# Actually ""s are just as good as 0's, but for concision we'll just say:
Carp::croak("protocols_allowed has to be an arrayref or 0, not \"$protocols_allowed\"!")
if $protocols_allowed and ref($protocols_allowed) ne 'ARRAY';
@@ -111,6 +114,8 @@ sub new
no_proxy => [ @{ $no_proxy } ],
protocols_allowed => $protocols_allowed,
protocols_forbidden => $protocols_forbidden,
+ allow_credentialed_redirects => $allow_credentialed_redirects,
+ allow_downgrade => $allow_downgrade,
requests_redirectable => $requests_redirectable,
send_te => $send_te,
}, $class;
@@ -360,6 +365,42 @@ sub request {
}
$referral->uri($referral_uri);

+ # Strip caller-supplied credential headers on cross-origin
+ # redirect (different scheme/host/port). Same fix shape as
+ # libcurl CVE-2018-1000007. Opt-out via
+ # allow_credentialed_redirects => 1.
+ unless ($self->{allow_credentialed_redirects}) {
+ my $orig = $request->uri;
+ my $new = $referral->uri;
+ my $orig_scheme = defined $orig->scheme ? $orig->scheme : q{};
+ my $new_scheme = defined $new->scheme ? $new->scheme : q{};
+ my $orig_host = defined $orig->host ? lc $orig->host : q{};
+ my $new_host = defined $new->host ? lc $new->host : q{};
+ my $orig_port = eval { $orig->port } || 0;
+ my $new_port = eval { $new->port } || 0;
+ if ( $orig_scheme ne $new_scheme
+ || $orig_host ne $new_host
+ || $orig_port != $new_port)
+ {
+ $referral->remove_header('Authorization', 'Proxy-Authorization');
+ }
+ }
+
+ # Refuse https->http downgrade by default. A caller who
+ # requested https reasonably expects end-to-end TLS; following
+ # a 3xx to plaintext leaks the body and remaining headers.
+ # Opt-out via allow_downgrade => 1.
+ my $orig_scheme = defined $request->uri->scheme ? $request->uri->scheme : q{};
+ my $new_scheme = defined $referral->uri->scheme ? $referral->uri->scheme : q{};
+ if ( $orig_scheme eq 'https'
+ && $new_scheme eq 'http'
+ && !$self->{allow_downgrade})
+ {
+ $response->header("Client-Warning" =>
+ "Refusing https->http redirect (set allow_downgrade => 1 to opt in)");
+ return $response;
+ }
+
return $response unless $self->redirect_ok($referral, $response);
return $self->request($referral, $arg, $size, $response);

@@ -660,6 +701,8 @@ sub is_protocol_supported
sub protocols_allowed { shift->_elem('protocols_allowed' , @_) }
sub protocols_forbidden { shift->_elem('protocols_forbidden' , @_) }
sub requests_redirectable { shift->_elem('requests_redirectable', @_) }
+sub allow_credentialed_redirects { shift->_elem('allow_credentialed_redirects', @_) }
+sub allow_downgrade { shift->_elem('allow_downgrade', @_) }


sub redirect_ok
@@ -1269,6 +1312,8 @@ The following options correspond to attr
KEY DEFAULT
----------- --------------------
agent "libwww-perl/#.###"
+ allow_credentialed_redirects undef
+ allow_downgrade undef
conn_cache undef
cookie_jar undef
default_headers HTTP::Headers->new
@@ -1285,6 +1330,18 @@ The following options correspond to attr
ssl_opts { verify_hostname => 1 }
timeout 180

+When following a 3xx redirect to a different origin (a different
+scheme, host, or port), LWP::UserAgent strips C<Authorization>
+and C<Proxy-Authorization> from the cloned request to avoid leaking
+caller-supplied credentials to the redirect target. Set
+C<allow_credentialed_redirects> to a true value to opt out and
+forward these headers across origins.
+
+A 3xx redirect that downgrades an C<https> request to plain C<http>
+is refused by default; the original response is returned with a
+C<Client-Warning> header explaining the refusal. Set C<allow_downgrade>
+to a true value to opt in to following such redirects.
+
The following additional options are also accepted: If the C<env_proxy> option
is passed in with a true value, then proxy settings are read from environment
variables (see L<LWP::UserAgent/env_proxy>). If C<env_proxy> isn't provided, the
@@ -1327,6 +1384,30 @@ string is appended to it.
The user agent string should be one or more simple product identifiers
with an optional version number separated by the C</> character.

+=head2 allow_credentialed_redirects
+
+ my $allow = $ua->allow_credentialed_redirects;
+ $ua->allow_credentialed_redirects( 1 );
+
+Get/set whether caller-supplied C<Authorization> and C<Proxy-Authorization>
+headers are forwarded across cross-origin 3xx redirects (a different scheme,
+host, or port). Defaults to a false value, meaning the headers are stripped
+on cross-origin redirects to avoid leaking credentials to the redirect target.
+Same-origin redirects always retain these headers.
+
+=head2 allow_downgrade
+
+ my $allow = $ua->allow_downgrade;
+ $ua->allow_downgrade( 1 );
+
+Get/set whether a 3xx redirect from an C<https> request to a plain
+C<http> URL is followed. Defaults to a false value, meaning such
+redirects are refused; the original response is returned with a
+C<Client-Warning> header. Set to a true value to opt in to following
+the redirect. Note that even when C<allow_downgrade> is true,
+cross-origin credential stripping still applies (see
+L</allow_credentialed_redirects>).
+
=head2 conn_cache

my $cache_obj = $ua->conn_cache;
1 change: 1 addition & 0 deletions debian/patches/series
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CVE-2026-8368.patch
Loading