summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrédéric Buclin <LpSolit@gmail.com>2011-12-28 23:11:44 +0100
committerFrédéric Buclin <LpSolit@gmail.com>2011-12-28 23:11:44 +0100
commit2d792a108434d9ea59ebf75ae09fb69cbab6fb71 (patch)
tree3da27d1b0158d793d42cf87bb3fd479de558b525
parentf8813fc6a94b4e8e6d5e77009458ed8cb5a856c7 (diff)
downloadbugzilla-2d792a108434d9ea59ebf75ae09fb69cbab6fb71.tar.gz
bugzilla-2d792a108434d9ea59ebf75ae09fb69cbab6fb71.tar.xz
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
-rw-r--r--Bugzilla/User.pm37
-rw-r--r--Bugzilla/WebService/Constants.pm1
-rw-r--r--Bugzilla/WebService/User.pm26
-rwxr-xr-xcreateaccount.cgi29
-rwxr-xr-xtoken.cgi4
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<Required> 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<Bugzilla::User> object.
+=item C<check_account_creation_enabled>
+
+Checks that users can create new user accounts, and throws an error
+if user creation is disabled.
+
+=item C<check_and_send_account_creation_confirmation($login)>
+
+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<is_available_username>
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.