diff options
author | Dylan William Hardison <dylan@hardison.net> | 2018-02-16 11:29:47 -0500 |
---|---|---|
committer | David Lawrence <dkl@mozilla.com> | 2018-02-16 11:29:47 -0500 |
commit | f31dbc9c2c868543dcc8904397c861881d59c45b (patch) | |
tree | 6eda98726f87a7b32a176ea0e89b88c6d1352a2d | |
parent | Bug 1303702 - bug history table 'when' column shows 00:00 only using sqlite (diff) | |
download | bugzilla-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.pm | 64 | ||||
-rwxr-xr-x | attachment.cgi | 1 |
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 |