From: Frédéric Buclin Date: Tue, 31 Jan 2012 16:06:30 +0000 (+0100) Subject: Bug 718319: (CVE-2012-0440) [SECURITY] JSON-RPC permits to bypass token checks and... X-Git-Tag: bugzilla-3.6.8~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dd9cba529992e9caf4a69ff1511360b6a44df3b4;p=thirdparty%2Fbugzilla.git Bug 718319: (CVE-2012-0440) [SECURITY] JSON-RPC permits to bypass token checks and can lead to CSRF (no victim's action required) r=dkl a=LpSolit --- diff --git a/Bugzilla/WebService/Constants.pm b/Bugzilla/WebService/Constants.pm index 3ee13527a5..b1779f16fb 100644 --- a/Bugzilla/WebService/Constants.pm +++ b/Bugzilla/WebService/Constants.pm @@ -25,6 +25,8 @@ our @EXPORT = qw( ERROR_UNKNOWN_FATAL ERROR_UNKNOWN_TRANSIENT + CONTENT_TYPE_BLACKLIST + WS_DISPATCH ); @@ -134,6 +136,14 @@ use constant ERROR_UNKNOWN_TRANSIENT => 32000; use constant ERROR_GENERAL => 999; +# Blacklist content types which can lead to CSRF when using POST with JSON-RPC. +# The default content type for JSON-RPC is application/json. +use constant CONTENT_TYPE_BLACKLIST => qw( + text/plain + application/x-www-form-urlencoded + multipart/form-data +); + sub WS_DISPATCH { # We "require" here instead of "use" above to avoid a dependency loop. require Bugzilla::Hook; diff --git a/Bugzilla/WebService/Server/JSONRPC.pm b/Bugzilla/WebService/Server/JSONRPC.pm index 096cecfbf9..05066db08b 100644 --- a/Bugzilla/WebService/Server/JSONRPC.pm +++ b/Bugzilla/WebService/Server/JSONRPC.pm @@ -228,6 +228,16 @@ sub _argument_type_check { Bugzilla->input_params($params); + # CSRF is possible when using |Content-Type: text/plain| with POST. + # There are some other content types which must also be banned for + # security reasons. + my $content_type = $self->cgi->content_type; + # The charset can be appended to the content type, so we use a regexp. + if (grep { $content_type =~ m{\Q$_\E}i } CONTENT_TYPE_BLACKLIST) { + ThrowUserError('json_rpc_illegal_content_type', + { content_type => $content_type }); + } + # This is the best time to do login checks. $self->handle_login(); diff --git a/template/en/default/global/user-error.html.tmpl b/template/en/default/global/user-error.html.tmpl index 76531a2403..bd15388903 100644 --- a/template/en/default/global/user-error.html.tmpl +++ b/template/en/default/global/user-error.html.tmpl @@ -996,6 +996,10 @@ [%+ constants.LOGIN_LOCKOUT_INTERVAL FILTER html %] minutes. [% END %] + [% ELSIF error == "json_rpc_illegal_content_type" %] + When using JSON-RPC over POST, you cannot use [% content_type FILTER html %] + as content type. The recommended content type is application/json. + [% ELSIF error == "json_rpc_post_only" %] For security reasons, you may only use JSON-RPC with the POST HTTP method.