aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDylan William Hardison <dylan@hardison.net>2018-02-16 11:29:47 -0500
committerDavid Lawrence <dkl@mozilla.com>2018-02-16 11:29:47 -0500
commitf31dbc9c2c868543dcc8904397c861881d59c45b (patch)
tree6eda98726f87a7b32a176ea0e89b88c6d1352a2d
parentBug 1303702 - bug history table 'when' column shows 00:00 only using sqlite (diff)
downloadbugzilla-f31dbc9c2c868543dcc8904397c861881d59c45b.tar.gz
bugzilla-f31dbc9c2c868543dcc8904397c861881d59c45b.tar.bz2
bugzilla-f31dbc9c2c868543dcc8904397c861881d59c45b.zip
Bug 1433400 (CVE-2018-5123) Prevent cross-site image requests from leaking contents of certain fields due to regex search
r=jfearn,a=dylan
-rw-r--r--Bugzilla/CGI.pm64
-rwxr-xr-xattachment.cgi1
2 files changed, 65 insertions, 0 deletions
diff --git a/Bugzilla/CGI.pm b/Bugzilla/CGI.pm
index 7df916b0c..19332b17a 100644
--- a/Bugzilla/CGI.pm
+++ b/Bugzilla/CGI.pm
@@ -283,6 +283,69 @@ sub close_standby_message {
}
}
+our $ALLOW_UNSAFE_RESPONSE = 0;
+# responding to text/plain or text/html is safe
+# responding to any request with a referer header is safe
+# some things need to have unsafe responses (attachment.cgi)
+# everything else should get a 403.
+sub _prevent_unsafe_response {
+ my ($self, $headers) = @_;
+ my $safe_content_type_re = qr{
+ ^ (*COMMIT) # COMMIT makes the regex faster
+ # by preventing back-tracking. see also perldoc pelre.
+ # application/x-javascript, xml, atom+xml, rdf+xml, xml-dtd, and json
+ (?: application/ (?: x(?: -javascript | ml (?: -dtd )? )
+ | (?: atom | rdf) \+ xml
+ | json )
+ # text/csv, text/calendar, text/plain, and text/html
+ | text/ (?: c (?: alendar | sv )
+ | plain
+ | html )
+ # used for HTTP push responses
+ | multipart/x-mixed-replace)
+ }sx;
+ my $safe_referer_re = do {
+ # Note that urlbase must end with a /.
+ # It almost certainly does, but let's be extra careful.
+ my $urlbase = correct_urlbase();
+ $urlbase =~ s{/$}{};
+ qr{
+ # Begins with literal urlbase
+ ^ (*COMMIT)
+ \Q$urlbase\E
+ # followed by a slash or end of string
+ (?: /
+ | $ )
+ }sx
+ };
+
+ return if $ALLOW_UNSAFE_RESPONSE;
+
+ if (Bugzilla->usage_mode == USAGE_MODE_BROWSER) {
+ # Safe content types are ones that arn't images.
+ # For now let's assume plain text and html are not valid images.
+ my $content_type = $headers->{'-type'} // $headers->{'-content_type'} // 'text/html';
+ my $is_safe_content_type = $content_type =~ $safe_content_type_re;
+
+ # Safe referers are ones that begin with the urlbase.
+ my $referer = $self->referer;
+ my $is_safe_referer = $referer && $referer =~ $safe_referer_re;
+
+ if (!$is_safe_referer && !$is_safe_content_type) {
+ print $self->SUPER::header(-type => 'text/html', -status => '403 Forbidden');
+ if ($content_type ne 'text/html') {
+ print "Untrusted Referer Header\n";
+ if ($ENV{MOD_PERL}) {
+ my $r = $self->r;
+ $r->rflush;
+ $r->status(200);
+ }
+ }
+ exit;
+ }
+ }
+}
+
# Override header so we can add the cookies in
sub header {
my $self = shift;
@@ -293,6 +356,7 @@ sub header {
# Since we're adding parameters below, we have to name it.
unshift(@_, '-type' => shift(@_));
}
+ $self->_prevent_unsafe_response({@_});
if (!$user->id && $user->authorizer->can_login
&& !$self->cookie('Bugzilla_login_request_cookie'))
diff --git a/attachment.cgi b/attachment.cgi
index 319e46ffb..cfcb8f5f9 100755
--- a/attachment.cgi
+++ b/attachment.cgi
@@ -40,6 +40,7 @@ use Encode::MIME::Header; # Required to alter Encode::Encoding{'MIME-Q'}.
local our $cgi = Bugzilla->cgi;
local our $template = Bugzilla->template;
local our $vars = {};
+local $Bugzilla::CGI::ALLOW_UNSAFE_RESPONSE = 1;
################################################################################
# Main Body Execution