Version in base suite: 4.4.6+dfsg-1.1+deb12u1 Base version: request-tracker4_4.4.6+dfsg-1.1+deb12u1 Target version: request-tracker4_4.4.6+dfsg-1.1+deb12u2 Base file: /srv/ftp-master.debian.org/ftp/pool/main/r/request-tracker4/request-tracker4_4.4.6+dfsg-1.1+deb12u1.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/r/request-tracker4/request-tracker4_4.4.6+dfsg-1.1+deb12u2.dsc .git-dpm | 4 NEWS | 11 changelog | 14 + patches/fix_CVE-2024-3262.diff | 185 +++++++++++++ patches/fix_CVE-2024-3262_2.diff | 83 ++++++ patches/series | 4 patches/upstream_4.4.6_cve:_patchset_2025-04-08.diff | 252 +++++++++++++++++++ patches/upstream_4.4.6_cve:_patchset_2025-04-11.diff | 46 +++ 8 files changed, 597 insertions(+), 2 deletions(-) diff -Nru request-tracker4-4.4.6+dfsg/debian/.git-dpm request-tracker4-4.4.6+dfsg/debian/.git-dpm --- request-tracker4-4.4.6+dfsg/debian/.git-dpm 2023-10-25 09:32:15.000000000 +0000 +++ request-tracker4-4.4.6+dfsg/debian/.git-dpm 2025-04-17 03:48:44.000000000 +0000 @@ -1,6 +1,6 @@ # see git-dpm(1) from git-dpm package -53ee266bc682e5ed66cd51cdc1540d4bbf437007 -53ee266bc682e5ed66cd51cdc1540d4bbf437007 +a9e5741a44b9ce67e1d6771b15c14941ed6d5a8e +a9e5741a44b9ce67e1d6771b15c14941ed6d5a8e 55d7d688b083f85df5b32d685ea4c2d6a4341705 55d7d688b083f85df5b32d685ea4c2d6a4341705 request-tracker4_4.4.6+dfsg.orig.tar.gz diff -Nru request-tracker4-4.4.6+dfsg/debian/NEWS request-tracker4-4.4.6+dfsg/debian/NEWS --- request-tracker4-4.4.6+dfsg/debian/NEWS 2023-10-25 09:32:15.000000000 +0000 +++ request-tracker4-4.4.6+dfsg/debian/NEWS 2025-04-17 03:48:48.000000000 +0000 @@ -1,3 +1,14 @@ +request-tracker4 (4.4.6+dfsg-1.1+deb12u2) bookworm-security; urgency=medium + + The default cipher for encrypting SMIME email has been changed from 3DES + (des3) to aes-128-cbc. If you need to use des3, use the new Crypt option. + + There is an information exposure vulnerability due to browser cache usage. + If you have sensitive information, you may wish to enable the new + $WebStrictBrowserCache option. + + -- Andrew Ruthven Sun, 13 Apr 2025 00:20:00 +1200 + request-tracker4 (4.4.6+dfsg-1.1+deb12u1) bookworm-security; urgency=medium It is strongly recommended that you ensure that .../REST/1.0/NoAuth is only diff -Nru request-tracker4-4.4.6+dfsg/debian/changelog request-tracker4-4.4.6+dfsg/debian/changelog --- request-tracker4-4.4.6+dfsg/debian/changelog 2023-10-25 09:32:15.000000000 +0000 +++ request-tracker4-4.4.6+dfsg/debian/changelog 2025-04-17 03:48:48.000000000 +0000 @@ -1,3 +1,17 @@ +request-tracker4 (4.4.6+dfsg-1.1+deb12u2) bookworm-security; urgency=medium + + * Apply upstream patches which fixes several security vulnerabilities. + - [CVE-2025-30087] Vulnerable to Cross Site Scripting via injection of + malicious parameters in a search URL. + - [CVE-2025-2545] RT uses the default OpenSSL cipher, 3DES (des3), for + encrypting SMIME email. This is an outdated cipher algorithm, so the + default is changed to aes-128-cbc. In addition, this is now configurable + so you can pick an alternate cipher now or in the future, or revert to + des3 if needed for compatibility + * [CVE-2024-3262] Cherry-pick upstream fixes (Closes: #1068452). + + -- Andrew Ruthven Thu, 17 Apr 2025 15:48:48 +1200 + request-tracker4 (4.4.6+dfsg-1.1+deb12u1) bookworm-security; urgency=medium * Apply upstream patch which fixes several security vulnerabilities diff -Nru request-tracker4-4.4.6+dfsg/debian/patches/fix_CVE-2024-3262.diff request-tracker4-4.4.6+dfsg/debian/patches/fix_CVE-2024-3262.diff --- request-tracker4-4.4.6+dfsg/debian/patches/fix_CVE-2024-3262.diff 1970-01-01 00:00:00.000000000 +0000 +++ request-tracker4-4.4.6+dfsg/debian/patches/fix_CVE-2024-3262.diff 2025-04-17 03:48:44.000000000 +0000 @@ -0,0 +1,185 @@ +From bcbaf00ae5f334c6874d65c5c6dc5e9da14148d2 Mon Sep 17 00:00:00 2001 +From: Andrew Ruthven +Date: Sun, 11 Aug 2024 19:04:01 +1200 +Subject: Add $WebStrictBrowserCache option to disable browser cache + +Cherry-picked from 5.0-trunk + +RT systems that store sensitive data may want to disable all +browser cache and back button behavior. This option enables +that and moves these headers to a separate Mason template +for easy override. + +See: https://owasp.org/www-project-web-security-testing-guide/v42/4-Web_Application_Security_Testing/04-Authentication_Testing/06-Testing_for_Browser_Cache_Weaknesses + +Patch-Name: fix_CVE-2024-3262.diff +Applied-Upstream: 5.0.6, commit:ea07e767eaef5b202e8883051616d09806b8b48a +Origin: vendor +Forwarded: not-needed +Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1068453 +--- + etc/RT_Config.pm.in | 14 ++++ + share/html/Elements/Header | 3 +- + share/html/Elements/HttpResponseHeaders | 99 +++++++++++++++++++++++++ + share/html/m/_elements/header | 3 +- + 4 files changed, 115 insertions(+), 4 deletions(-) + create mode 100644 share/html/Elements/HttpResponseHeaders + +diff --git a/etc/RT_Config.pm.in b/etc/RT_Config.pm.in +index 6b0284dd..c9eb309d 100644 +--- a/etc/RT_Config.pm.in ++++ b/etc/RT_Config.pm.in +@@ -2750,6 +2750,20 @@ connections. + + Set($WebSecureCookies, 0); + ++=item C<$WebStrictBrowserCache> ++ ++As part of normal operation, browsers typically store some browsing ++history, enabling the Back button to work. Browsers also often ++cache pages in the browsing history to improve performance. ++ ++Enable this option if you are using RT with highly sensitive ++information and want to signal the browser to not store any history ++or cache any data. The default is disabled. ++ ++=cut ++ ++Set($WebStrictBrowserCache, 0); ++ + =item C<$WebHttpOnlyCookies> + + Default RT's session cookie to not being directly accessible to +diff --git a/share/html/Elements/Header b/share/html/Elements/Header +index ad17a431..9281342d 100644 +--- a/share/html/Elements/Header ++++ b/share/html/Elements/Header +@@ -118,8 +118,7 @@ $lang = $session{'CurrentUser'}->LanguageHandle->language_tag + && $session{'CurrentUser'}->LanguageHandle + && $session{'CurrentUser'}->LanguageHandle->language_tag; + +-$r->headers_out->{'Pragma'} = 'no-cache'; +-$r->headers_out->{'Cache-control'} = 'no-cache'; ++$m->comp('/Elements/HttpResponseHeaders'); + + my $id = $m->request_comp->path; + $id =~ s|^/||g; +diff --git a/share/html/Elements/HttpResponseHeaders b/share/html/Elements/HttpResponseHeaders +new file mode 100644 +index 00000000..3b452f01 +--- /dev/null ++++ b/share/html/Elements/HttpResponseHeaders +@@ -0,0 +1,99 @@ ++%# BEGIN BPS TAGGED BLOCK {{{ ++%# ++%# COPYRIGHT: ++%# ++%# This software is Copyright (c) 1996-2023 Best Practical Solutions, LLC ++%# ++%# ++%# (Except where explicitly superseded by other copyright notices) ++%# ++%# ++%# LICENSE: ++%# ++%# This work is made available to you under the terms of Version 2 of ++%# the GNU General Public License. A copy of that license should have ++%# been provided with this software, but in any event can be snarfed ++%# from www.gnu.org. ++%# ++%# This work is distributed in the hope that it will be useful, but ++%# WITHOUT ANY WARRANTY; without even the implied warranty of ++%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++%# General Public License for more details. ++%# ++%# You should have received a copy of the GNU General Public License ++%# along with this program; if not, write to the Free Software ++%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++%# 02110-1301 or visit their web page on the internet at ++%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. ++%# ++%# ++%# CONTRIBUTION SUBMISSION POLICY: ++%# ++%# (The following paragraph is not intended to limit the rights granted ++%# to you to modify and distribute this software under the terms of ++%# the GNU General Public License and is only of importance to you if ++%# you choose to contribute your changes and enhancements to the ++%# community by submitting them to Best Practical Solutions, LLC.) ++%# ++%# By intentionally submitting any modifications, corrections or ++%# derivatives to this work, or any other work intended for use with ++%# Request Tracker, to Best Practical Solutions, LLC, you confirm that ++%# you are the copyright holder for those contributions and you grant ++%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, ++%# royalty-free, perpetual, license to use, copy, create derivative ++%# works based on those contributions, and sublicense and distribute ++%# those contributions and any derivatives thereof. ++%# ++%# END BPS TAGGED BLOCK }}} ++<%INIT> ++ ++# Since data in the DB can change at any time, the default headers ++# for dynamic content (content generated from most Mason templates) is: ++# ++# Cache-control: no-cache ++# Pragma: no-cache ++# Expires: [a short time in the past to account for any time drift] ++ ++# Pragma is deprecated and usually ignored if Cache-control is sent. ++# Should only be used by HTTP/1.0 clients. ++$r->headers_out->{'Pragma'} = 'no-cache'; ++ ++my $cache_control = 'no-cache'; ++ ++my $expires = RT::Date->new(RT->SystemUser); ++$expires->SetToNow; ++ ++if ( $MaxAgeSeconds && !RT->Config->Get('WebStrictBrowserCache') ) { ++ $expires->AddSeconds($MaxAgeSeconds); ++ ++ # Expires is an older header and has been superseded by Cache-control ++ # and max-age, so set that also. New browsers will use max-age and ++ # ignore Expires. ++ ++ # We're allowing a short cache, so replace no-cache with max-age. ++ ++ $cache_control = "max-age=$MaxAgeSeconds, private" ++} ++else { ++ # Setting Expires to 0, a common approach to "immediately expired" ++ # doesn't send an Expires header from Mason, so set a little in the past. ++ ++ $expires->AddSeconds(-30); ++ $cache_control .= ', max-age=0'; ++} ++ ++$r->headers_out->{'Expires'} = $expires->RFC2616; ++ ++if ( RT->Config->Get('WebStrictBrowserCache') ) { ++ ++ # Instruct the browser not to cache or store anything ++ $cache_control .= ', no-store, must-revalidate, s-maxage=0'; ++} ++ ++$r->headers_out->{'Cache-control'} = $cache_control; ++ ++$m->callback( %ARGS, CallbackName => 'End' ); ++ ++<%ARGS> ++$MaxAgeSeconds => undef # Time in seconds to allow for cache ++ +diff --git a/share/html/m/_elements/header b/share/html/m/_elements/header +index 0bb72e28..2a192dc1 100644 +--- a/share/html/m/_elements/header ++++ b/share/html/m/_elements/header +@@ -50,8 +50,7 @@ $title => loc('RT for [_1]', RT->Config->Get('rtname')) + $show_home_button => 1 + + <%init> +-$r->headers_out->{'Pragma'} = 'no-cache'; +-$r->headers_out->{'Cache-control'} = 'no-cache'; ++$m->comp('/Elements/HttpResponseHeaders'); + + + diff -Nru request-tracker4-4.4.6+dfsg/debian/patches/fix_CVE-2024-3262_2.diff request-tracker4-4.4.6+dfsg/debian/patches/fix_CVE-2024-3262_2.diff --- request-tracker4-4.4.6+dfsg/debian/patches/fix_CVE-2024-3262_2.diff 1970-01-01 00:00:00.000000000 +0000 +++ request-tracker4-4.4.6+dfsg/debian/patches/fix_CVE-2024-3262_2.diff 2025-04-17 03:48:44.000000000 +0000 @@ -0,0 +1,83 @@ +From a9e5741a44b9ce67e1d6771b15c14941ed6d5a8e Mon Sep 17 00:00:00 2001 +From: Andrew Ruthven +Date: Sun, 11 Aug 2024 19:10:13 +1200 +Subject: Convert other Mason templates to new headers template + +Cherry-picked from 5.0-trunk as a continuation of the fix for CVE-2024-3262. + +27bd738eaf created a single method in Web.pm, CacheControlExpiresHeaders +to generate HTTP response headers, specifically those related to +caching instructions for browsers. That was applied to Helpers, but +wasn't used for regular RT pages. + +Later, 915eb4b7d0 sought to fix a regression that resulted in +cache headers not being sent for static files returned via +Plack::Middleware::Static. That fix went to great lengths to +try to re-use functionality from CacheControlExpiresHeaders, +including moving all of the code to GetStaticHeaders. This +probably wasn't really needed since it's reasonable to allow +the special case static handler to send it's own one or two headers. +It also made the code confusing since dynamic pages in Mason +called CacheControlExpiresHeaders, which then called GetStaticHeaders +to get headers for responses that were not static. + +This update gets all of the Mason web pages using the same code +for these headers. It leaves the current methods in place to continue +handling static files. That can likely be simplified and cleaned up +in a future commit. + +Patch-Name: fix_CVE-2024-3262_2.diff +Applied-Upstream: 5.0.6, commit:468f86bd3e82c3b5b5ef7087d416a7509d4b1abe +Origin: vendor +Forwarded: not-needed +Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1068453 +--- + share/html/Helpers/Autocomplete/autohandler | 6 ++---- + share/html/Helpers/autohandler | 5 ++--- + t/web/helpers-http-cache-headers.t | 4 ++-- + 3 files changed, 6 insertions(+), 9 deletions(-) + +diff --git a/share/html/Helpers/Autocomplete/autohandler b/share/html/Helpers/Autocomplete/autohandler +index 63463278..33312ca1 100644 +--- a/share/html/Helpers/Autocomplete/autohandler ++++ b/share/html/Helpers/Autocomplete/autohandler +@@ -46,8 +46,6 @@ + %# + %# END BPS TAGGED BLOCK }}} + <%init> +- RT::Interface::Web::CacheControlExpiresHeaders( Time => 2 * 60 ); +- +- $m->call_next; ++$m->comp('/Elements/HttpResponseHeaders', MaxAgeSeconds => 2 * 60); ++$m->call_next; + +- +diff --git a/share/html/Helpers/autohandler b/share/html/Helpers/autohandler +index 6c74ee3f..3466485b 100644 +--- a/share/html/Helpers/autohandler ++++ b/share/html/Helpers/autohandler +@@ -46,7 +46,6 @@ + %# + %# END BPS TAGGED BLOCK }}} + <%init> +- RT::Interface::Web::CacheControlExpiresHeaders( Time => 'no-cache' ); +- +- $m->call_next; ++$m->comp('/Elements/HttpResponseHeaders'); ++$m->call_next; + +diff --git a/t/web/helpers-http-cache-headers.t b/t/web/helpers-http-cache-headers.t +index 1ffef2de..a586d6a5 100644 +--- a/t/web/helpers-http-cache-headers.t ++++ b/t/web/helpers-http-cache-headers.t +@@ -73,8 +73,8 @@ diag "set up expected date headers"; + 'Expires' => 'Sun, 05 May 2013 15:28:19 GMT', + }, + default => { +- 'Cache-Control' => 'no-cache', +- 'Expires' => 'Fri, 05 Apr 2013 15:28:19 GMT', ++ 'Cache-Control' => 'no-cache, max-age=0', ++ 'Expires' => 'Fri, 05 Apr 2013 15:27:49 GMT', + }, + }; + diff -Nru request-tracker4-4.4.6+dfsg/debian/patches/series request-tracker4-4.4.6+dfsg/debian/patches/series --- request-tracker4-4.4.6+dfsg/debian/patches/series 2023-10-25 09:32:15.000000000 +0000 +++ request-tracker4-4.4.6+dfsg/debian/patches/series 2025-04-17 03:48:44.000000000 +0000 @@ -25,3 +25,7 @@ fix_expired_certs.dif upstream_4.4.6_cve:_patchset_2023-09-26.diff upstream_4.4.6_cve:_patchset_2023-09-26-tests.diff +upstream_4.4.6_cve:_patchset_2025-04-08.diff +upstream_4.4.6_cve:_patchset_2025-04-11.diff +fix_CVE-2024-3262.diff +fix_CVE-2024-3262_2.diff diff -Nru request-tracker4-4.4.6+dfsg/debian/patches/upstream_4.4.6_cve:_patchset_2025-04-08.diff request-tracker4-4.4.6+dfsg/debian/patches/upstream_4.4.6_cve:_patchset_2025-04-08.diff --- request-tracker4-4.4.6+dfsg/debian/patches/upstream_4.4.6_cve:_patchset_2025-04-08.diff 1970-01-01 00:00:00.000000000 +0000 +++ request-tracker4-4.4.6+dfsg/debian/patches/upstream_4.4.6_cve:_patchset_2025-04-08.diff 2025-04-17 03:48:44.000000000 +0000 @@ -0,0 +1,252 @@ +From 174501199bdfb77e9c0d32ea5e6458aff56bf7b0 Mon Sep 17 00:00:00 2001 +From: Andrew Ruthven +Date: Sat, 12 Apr 2025 23:49:14 +1200 +Subject: Fix two security issues in RT. + +* RT is vulnerable to Cross Site Scripting via injection of malicious + parameters in a search URL. This vulnerability is assigned CVE-2025-30087. +* RT uses the default OpenSSL cipher, 3DES (des3), for encrypting SMIME email. + This is an outdated cipher algorithm, so the default is changed to + aes-128-cbc. In addition, we have made this option configurable so you can + pick an alternate cipher now or in the future, or revert to des3 if needed + for compatibility. This vulnerability is assigned CVE-2025-2545. + +Patch-Name: upstream_4.4.6_cve:_patchset_2025-04-08.diff +Author: Best Practical +Forwarded: not-needed +Applied: 4.4.8 +--- + etc/RT_Config.pm | 24 ++++++++++++++ + lib/RT/Crypt/SMIME.pm | 2 +- + lib/RT/Interface/Web.pm | 51 +++++++++++++++++++++++++++-- + share/html/Asset/Elements/TSVExport | 2 +- + share/html/Elements/CollectionList | 4 +-- + share/html/Elements/ScrubHTML | 2 +- + share/html/Elements/TSVExport | 2 +- + share/html/Search/Build.html | 2 +- + share/html/Search/Edit.html | 2 +- + 9 files changed, 80 insertions(+), 11 deletions(-) + +diff --git a/etc/RT_Config.pm b/etc/RT_Config.pm +index 9ae33228..6ff1681e 100644 +--- a/etc/RT_Config.pm ++++ b/etc/RT_Config.pm +@@ -2612,6 +2612,26 @@ higher numbers denoting greater effort. + + Set($BcryptCost, 12); + ++=item C<@RestrictLinkDomains> ++ ++This sets a list of external domains that RT is allowed to link to. If this ++setting is empty, no external domains are allowed. ++ ++Currently, this restriction only applies to links in Format parameter for ++search results. All external links whose domains are not in the list will ++be removed. ++ ++E.g. ++ ++ Set(@RestrictLinkDomains, ("example.com", "*.trusted.com")); ++ ++ example.com # Allow links to "example.com" ++ *.trusted.com # Allow links to any one-level subdomain of "trusted.com" ++ ++=cut ++ ++Set(@RestrictLinkDomains, ()); ++ + =back + + +@@ -3123,6 +3143,9 @@ Set C to the timeout in seconds for + downloading a CRL or an issuer certificate (the latter is used when + checking against OCSP). The default timeout is 30 seconds. + ++Set C to the encryption algorithm to use. By default, it's ++C. ++ + See L for details. + + =back +@@ -3140,6 +3163,7 @@ Set( %SMIME, + CheckCRL => 0, + CheckOCSP => 0, + CheckRevocationDownloadTimeout => 30, ++ Cipher => 'aes-128-cbc', + ); + + =head2 GnuPG configuration +diff --git a/lib/RT/Crypt/SMIME.pm b/lib/RT/Crypt/SMIME.pm +index 67764d55..c98cecc1 100644 +--- a/lib/RT/Crypt/SMIME.pm ++++ b/lib/RT/Crypt/SMIME.pm +@@ -425,7 +425,7 @@ sub _SignEncrypt { + $key = $key_file; + } + push @commands, [ +- $self->OpenSSLPath, qw(smime -encrypt -des3), ++ $self->OpenSSLPath, qw(smime -encrypt), '-' . ( $opts->{Cipher} || 'aes-128-cbc' ), + map { $_->filename } @keys + ]; + } +diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm +index 87102028..ea11a90d 100644 +--- a/lib/RT/Interface/Web.pm ++++ b/lib/RT/Interface/Web.pm +@@ -4615,12 +4615,20 @@ Removes unsafe and undesired HTML from the passed content + =cut + + my $SCRUBBER; ++my $RESTRICTIVE_SCRUBBER; + sub ScrubHTML { + my $Content = shift; +- $SCRUBBER = _NewScrubber() unless $SCRUBBER; ++ my %args = @_; + + $Content = '' if !defined($Content); +- return $SCRUBBER->scrub($Content); ++ if ( $args{Restrictive} ) { ++ $RESTRICTIVE_SCRUBBER = _NewScrubber(Restrictive => 1) unless $RESTRICTIVE_SCRUBBER; ++ return $RESTRICTIVE_SCRUBBER->scrub($Content); ++ } ++ else { ++ $SCRUBBER = _NewScrubber() unless $SCRUBBER; ++ return $SCRUBBER->scrub($Content); ++ } + } + + =head2 _NewScrubber +@@ -4702,7 +4710,44 @@ if (RT->Config->Get('ShowTransactionImages') or RT->Config->Get('ShowRemoteImage + $SCRUBBER_RULES{'img'}->{'src'} = join "|", @src; + } + ++our %RESTRICTIVE_SCRUBBER_RULES = ( ++ a => { ++ href => sub { ++ my ( $self, $tag, $attr, $href ) = @_; ++ return $href unless $href; ++ ++ # Allow internal RT macros like __WebPath__, etc. ++ return $href if $href =~ qr{^(?:/|__Web(?:Path|HomePath|BaseURL|URL)__)}i; ++ ++ my $uri = URI->new($href); ++ unless ( $uri->can("host") && $uri->host ) { ++ RT->Logger->warn("Unknown link: $href"); ++ return ''; ++ } ++ ++ my $rt_host = RT::Interface::Web::_NormalizeHost( RT->Config->Get('WebBaseURL') )->host; ++ my $host = lc $uri->host; ++ for my $allowed_domain ( $rt_host, @{ RT->Config->Get('RestrictLinkDomains') || [] } ) { ++ if ( $allowed_domain =~ /\*/ ) { ++ ++ # Turn a literal * into a domain component or partial component match. ++ my $regex = join "[a-zA-Z0-9\-]*", map { quotemeta($_) } ++ split /\*/, $allowed_domain; ++ return $href if $host =~ /^$regex$/i; ++ } ++ else { ++ return $href if $host eq lc($allowed_domain); ++ } ++ } ++ ++ RT->Logger->warning("Blocked link: $href"); ++ return ''; ++ }, ++ }, ++); ++ + sub _NewScrubber { ++ my %args = @_; + require HTML::Scrubber; + my $scrubber = HTML::Scrubber->new(); + +@@ -4730,7 +4775,7 @@ sub _NewScrubber { + ); + $scrubber->deny(qw[*]); + $scrubber->allow(@SCRUBBER_ALLOWED_TAGS); +- $scrubber->rules(%SCRUBBER_RULES); ++ $scrubber->rules( $args{Restrictive} ? %RESTRICTIVE_SCRUBBER_RULES : %SCRUBBER_RULES ); + + # Scrubbing comments is vital since IE conditional comments can contain + # arbitrary HTML and we'd pass it right on through. +diff --git a/share/html/Asset/Elements/TSVExport b/share/html/Asset/Elements/TSVExport +index 660a19eb..646adb1a 100644 +--- a/share/html/Asset/Elements/TSVExport ++++ b/share/html/Asset/Elements/TSVExport +@@ -58,7 +58,7 @@ require HTML::Entities; + + $r->content_type('application/vnd.ms-excel'); + +-my $DisplayFormat = $m->comp('/Elements/ScrubHTML', Content => $Format); ++my $DisplayFormat = $m->comp('/Elements/ScrubHTML', Content => $Format, Restrictive => 1); + + my @Format = $m->comp('/Elements/CollectionAsTable/ParseFormat', Format => $DisplayFormat); + +diff --git a/share/html/Elements/CollectionList b/share/html/Elements/CollectionList +index fff3c7d8..499442de 100644 +--- a/share/html/Elements/CollectionList ++++ b/share/html/Elements/CollectionList +@@ -93,8 +93,8 @@ $Collection->GotoPage( $Page - 1 ); # SB uses page 0 as the first page + $DisplayFormat ||= $Format; + + # Scrub the html of the format string to remove any potential nasties. +-$Format = $m->comp('/Elements/ScrubHTML', Content => $Format); +-$DisplayFormat = $m->comp('/Elements/ScrubHTML', Content => $DisplayFormat); ++$Format = $m->comp('/Elements/ScrubHTML', Content => $Format, Restrictive => 1); ++$DisplayFormat = $m->comp('/Elements/ScrubHTML', Content => $DisplayFormat, Restrictive => 1); + + my @Format = $m->comp('/Elements/CollectionAsTable/ParseFormat', Format => $DisplayFormat); + +diff --git a/share/html/Elements/ScrubHTML b/share/html/Elements/ScrubHTML +index 2a1c7f60..84636070 100644 +--- a/share/html/Elements/ScrubHTML ++++ b/share/html/Elements/ScrubHTML +@@ -46,7 +46,7 @@ + %# + %# END BPS TAGGED BLOCK }}} + <%init> +-return ScrubHTML($Content); ++return ScrubHTML($Content, %ARGS); + + <%args> + $Content => undef +diff --git a/share/html/Elements/TSVExport b/share/html/Elements/TSVExport +index 5f9427f9..5a13fecb 100644 +--- a/share/html/Elements/TSVExport ++++ b/share/html/Elements/TSVExport +@@ -62,7 +62,7 @@ $Class ||= $Collection->ColumnMapClassName; + $r->content_type('application/vnd.ms-excel'); + $r->header_out( 'Content-disposition' => "attachment; filename=$Filename" ) if $Filename; + +-my $DisplayFormat = $m->comp('/Elements/ScrubHTML', Content => $Format); ++my $DisplayFormat = $m->comp('/Elements/ScrubHTML', Content => $Format, Restrictive => 1); + + my @Format = $m->comp('/Elements/CollectionAsTable/ParseFormat', Format => $DisplayFormat); + +diff --git a/share/html/Search/Build.html b/share/html/Search/Build.html +index 7b134f57..f80459c5 100644 +--- a/share/html/Search/Build.html ++++ b/share/html/Search/Build.html +@@ -159,7 +159,7 @@ if ( $NewQuery ) { + } + if ( $query{'Format'} ) { + # Clean unwanted junk from the format +- $query{'Format'} = $m->comp( '/Elements/ScrubHTML', Content => $query{'Format'} ); ++ $query{'Format'} = $m->comp( '/Elements/ScrubHTML', Content => $query{'Format'}, Restrictive => 1 ); + } + } + +diff --git a/share/html/Search/Edit.html b/share/html/Search/Edit.html +index cdb7c1c4..f4e42e9d 100644 +--- a/share/html/Search/Edit.html ++++ b/share/html/Search/Edit.html +@@ -64,7 +64,7 @@ + + <%INIT> + my $title = loc("Edit Query"); +-$Format = $m->comp('/Elements/ScrubHTML', Content => $Format); ++$Format = $m->comp('/Elements/ScrubHTML', Content => $Format, Restrictive => 1); + my $QueryString = $m->comp('/Elements/QueryString', + Query => $Query, + Format => $Format, diff -Nru request-tracker4-4.4.6+dfsg/debian/patches/upstream_4.4.6_cve:_patchset_2025-04-11.diff request-tracker4-4.4.6+dfsg/debian/patches/upstream_4.4.6_cve:_patchset_2025-04-11.diff --- request-tracker4-4.4.6+dfsg/debian/patches/upstream_4.4.6_cve:_patchset_2025-04-11.diff 1970-01-01 00:00:00.000000000 +0000 +++ request-tracker4-4.4.6+dfsg/debian/patches/upstream_4.4.6_cve:_patchset_2025-04-11.diff 2025-04-17 03:48:44.000000000 +0000 @@ -0,0 +1,46 @@ +From e4946c5a125dce828dda6ff7bd60d3be10d64fb3 Mon Sep 17 00:00:00 2001 +From: Andrew Ruthven +Date: Sat, 12 Apr 2025 23:53:40 +1200 +Subject: Improve fix to CVE-2025-30087 + +After releasing the fix for CVE-2025-30087, Best Practical became aware that the +new linking restrictions were too strict in some cases, causing legitimate +links to stop working. This is most pronounced for users running RTIR, where +many links stop working. This patch should resolve that. + +Patch-Name: upstream_4.4.6_cve:_patchset_2025-04-11.diff +Author: Best Practical +Forwarded: not-needed +Applied: 4.4.8 +--- + lib/RT/Interface/Web.pm | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm +index ea11a90d..45ae4f1c 100644 +--- a/lib/RT/Interface/Web.pm ++++ b/lib/RT/Interface/Web.pm +@@ -4712,12 +4712,13 @@ if (RT->Config->Get('ShowTransactionImages') or RT->Config->Get('ShowRemoteImage + + our %RESTRICTIVE_SCRUBBER_RULES = ( + a => { ++ %SCRUBBER_ALLOWED_ATTRIBUTES, + href => sub { + my ( $self, $tag, $attr, $href ) = @_; + return $href unless $href; + + # Allow internal RT macros like __WebPath__, etc. +- return $href if $href =~ qr{^(?:/|__Web(?:Path|HomePath|BaseURL|URL)__)}i; ++ return $href if $href !~ /^\w+:/ && $href =~ $SCRUBBER_ALLOWED_ATTRIBUTES{'href'}; + + my $uri = URI->new($href); + unless ( $uri->can("host") && $uri->host ) { +@@ -4775,7 +4776,7 @@ sub _NewScrubber { + ); + $scrubber->deny(qw[*]); + $scrubber->allow(@SCRUBBER_ALLOWED_TAGS); +- $scrubber->rules( $args{Restrictive} ? %RESTRICTIVE_SCRUBBER_RULES : %SCRUBBER_RULES ); ++ $scrubber->rules( %SCRUBBER_RULES, $args{Restrictive} ? %RESTRICTIVE_SCRUBBER_RULES : () ); + + # Scrubbing comments is vital since IE conditional comments can contain + # arbitrary HTML and we'd pass it right on through.