From 2d792a108434d9ea59ebf75ae09fb69cbab6fb71 Mon Sep 17 00:00:00 2001 From: Frédéric Buclin Date: Wed, 28 Dec 2011 23:11:44 +0100 Subject: Bug 711714: (CVE-2011-3667) [SECURITY] The User.offer_account_by_email WebService method lets you create new user accounts independently of the value of Bugzilla::Auth::Verify::*::user_can_create_account r=glob a=LpSolit --- Bugzilla/User.pm | 37 +++++++++++++++++++++++++++++++++++++ Bugzilla/WebService/Constants.pm | 1 + Bugzilla/WebService/User.pm | 26 +++++++------------------- createaccount.cgi | 29 +++-------------------------- token.cgi | 4 ++++ 5 files changed, 52 insertions(+), 45 deletions(-) diff --git a/Bugzilla/User.pm b/Bugzilla/User.pm index ccb73cb66..5f430833b 100644 --- a/Bugzilla/User.pm +++ b/Bugzilla/User.pm @@ -1965,6 +1965,32 @@ sub is_available_username { return 1; } +sub check_account_creation_enabled { + my $self = shift; + + # If we're using e.g. LDAP for login, then we can't create a new account. + $self->authorizer->user_can_create_account + || ThrowUserError('auth_cant_create_account'); + + Bugzilla->params->{'createemailregexp'} + || ThrowUserError('account_creation_disabled'); +} + +sub check_and_send_account_creation_confirmation { + my ($self, $login) = @_; + + $login = $self->check_login_name_for_creation($login); + my $creation_regexp = Bugzilla->params->{'createemailregexp'}; + + if ($login !~ /$creation_regexp/i) { + ThrowUserError('account_creation_restricted'); + } + + # Create and send a token for this new account. + require Bugzilla::Token; + Bugzilla::Token::issue_new_user_account_token($login); +} + # This is used in a few performance-critical areas where we don't want to # do check() and pull all the user data from the database. sub login_to_id { @@ -2516,6 +2542,17 @@ Params: login_name - B The login name for the new user. Takes a username as its only argument. Throws an error if there is no user with that username. Returns a C object. +=item C + +Checks that users can create new user accounts, and throws an error +if user creation is disabled. + +=item C + +If the user request for a new account passes validation checks, an email +is sent to this user for confirmation. Otherwise an error is thrown +indicating why the request has been rejected. + =item C Returns a boolean indicating whether or not the supplied username is diff --git a/Bugzilla/WebService/Constants.pm b/Bugzilla/WebService/Constants.pm index 123b14d68..ab3111eed 100644 --- a/Bugzilla/WebService/Constants.pm +++ b/Bugzilla/WebService/Constants.pm @@ -130,6 +130,7 @@ use constant WS_ERROR_CODE => { # User errors are 500-600. account_exists => 500, illegal_email_address => 501, + auth_cant_create_account => 501, account_creation_disabled => 501, account_creation_restricted => 501, password_too_short => 502, diff --git a/Bugzilla/WebService/User.pm b/Bugzilla/WebService/User.pm index 2d9276cc3..f8704a947 100644 --- a/Bugzilla/WebService/User.pm +++ b/Bugzilla/WebService/User.pm @@ -28,7 +28,6 @@ use Bugzilla::Error; use Bugzilla::Group; use Bugzilla::User; use Bugzilla::Util qw(trim); -use Bugzilla::Token; use Bugzilla::WebService::Util qw(filter validate); # Don't need auth to login @@ -91,19 +90,8 @@ sub offer_account_by_email { my $email = trim($params->{email}) || ThrowCodeError('param_required', { param => 'email' }); - my $createexp = Bugzilla->params->{'createemailregexp'}; - if (!$createexp) { - ThrowUserError("account_creation_disabled"); - } - elsif ($email !~ /$createexp/i) { - ThrowUserError("account_creation_restricted"); - } - - $email = Bugzilla::User->check_login_name_for_creation($email); - - # Create and send a token for this new account. - Bugzilla::Token::issue_new_user_account_token($email); - + Bugzilla->user->check_account_creation_enabled; + Bugzilla->user->check_and_send_account_creation_confirmation($email); return undef; } @@ -396,14 +384,14 @@ This is the recommended way to create a Bugzilla account. =over -=item 500 (Illegal Email Address) +=item 500 (Account Already Exists) -This Bugzilla does not allow you to create accounts with the format of -email address you specified. Account creation may be entirely disabled. +An account with that email address already exists in Bugzilla. -=item 501 (Account Already Exists) +=item 501 (Illegal Email Address) -An account with that email address already exists in Bugzilla. +This Bugzilla does not allow you to create accounts with the format of +email address you specified. Account creation may be entirely disabled. =back diff --git a/createaccount.cgi b/createaccount.cgi index 09999865f..acc63e891 100755 --- a/createaccount.cgi +++ b/createaccount.cgi @@ -31,35 +31,19 @@ use lib qw(. lib); use Bugzilla; use Bugzilla::Constants; use Bugzilla::Error; -use Bugzilla::User; -use Bugzilla::BugMail; -use Bugzilla::Util; use Bugzilla::Token; # Just in case someone already has an account, let them get the correct footer # on an error message. The user is logged out just after the account is # actually created. my $user = Bugzilla->login(LOGIN_OPTIONAL); - -my $dbh = Bugzilla->dbh; my $cgi = Bugzilla->cgi; my $template = Bugzilla->template; -my $vars = {}; - -$vars->{'doc_section'} = 'myaccount.html'; +my $vars = { doc_section => 'myaccount.html' }; print $cgi->header(); -# If we're using LDAP for login, then we can't create a new account here. -unless ($user->authorizer->user_can_create_account) { - ThrowUserError("auth_cant_create_account"); -} - -my $createexp = Bugzilla->params->{'createemailregexp'}; -unless ($createexp) { - ThrowUserError("account_creation_disabled"); -} - +$user->check_account_creation_enabled; my $login = $cgi->param('login'); if (defined($login)) { @@ -68,16 +52,9 @@ if (defined($login)) { my $token = $cgi->param('token'); check_hash_token($token, ['create_account']); - $login = Bugzilla::User->check_login_name_for_creation($login); + $user->check_and_send_account_creation_confirmation($login); $vars->{'login'} = $login; - if ($login !~ /$createexp/i) { - ThrowUserError("account_creation_restricted"); - } - - # Create and send a token for this new account. - Bugzilla::Token::issue_new_user_account_token($login); - $template->process("account/created.html.tmpl", $vars) || ThrowTemplateError($template->error()); exit; diff --git a/token.cgi b/token.cgi index c43acdbfd..048670a1c 100755 --- a/token.cgi +++ b/token.cgi @@ -298,6 +298,8 @@ sub cancelChangeEmail { sub request_create_account { my ($date, $login_name, $token) = @_; + Bugzilla->user->check_account_creation_enabled; + $vars->{'token'} = $token; $vars->{'email'} = $login_name . Bugzilla->params->{'emailsuffix'}; $vars->{'expiration_ts'} = ctime(str2time($date) + MAX_TOKEN_AGE * 86400); @@ -310,6 +312,8 @@ sub request_create_account { sub confirm_create_account { my ($login_name, $token) = @_; + Bugzilla->user->check_account_creation_enabled; + my $password = $cgi->param('passwd1') || ''; validate_password($password, $cgi->param('passwd2') || ''); # Make sure that these never show up anywhere in the UI. -- cgit v1.2.3-24-g4f1b