From 93815fc7619567cc962e053280c5ed0b19492feb Mon Sep 17 00:00:00 2001 From: "lpsolit%gmail.com" <> Date: Sun, 15 Oct 2006 05:02:09 +0000 Subject: Bug 281181: [SECURITY] It's way too easy to delete versions/components/milestones etc... - Patch by Frédéric Buclin r=mkanat a=myk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Bugzilla/Token.pm | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 3 deletions(-) (limited to 'Bugzilla/Token.pm') diff --git a/Bugzilla/Token.pm b/Bugzilla/Token.pm index f00e65280..a0f6b0c8e 100644 --- a/Bugzilla/Token.pm +++ b/Bugzilla/Token.pm @@ -18,6 +18,7 @@ # Rights Reserved. # # Contributor(s): Myk Melez +# Frédéric Buclin ################################################################################ # Module Initialization @@ -36,6 +37,11 @@ use Bugzilla::Util; use Date::Format; use Date::Parse; +use File::Basename; + +use base qw(Exporter); + +@Bugzilla::Token::EXPORT = qw(issue_session_token check_token_data delete_token); ################################################################################ # Public Functions @@ -156,7 +162,7 @@ sub IssuePasswordToken { MessageToMTA($message); } -sub IssueSessionToken { +sub issue_session_token { # Generates a random token, adds it to the tokens table, and returns # the token to the caller. @@ -243,7 +249,7 @@ sub Cancel { MessageToMTA($message); # Delete the token from the database. - DeleteToken($token); + delete_token($token); } sub DeletePasswordTokens { @@ -279,6 +285,7 @@ sub GetTokenData { my $dbh = Bugzilla->dbh; return unless defined $token; + $token = clean_text($token); trick_taint($token); return $dbh->selectrow_array( @@ -288,7 +295,7 @@ sub GetTokenData { } # Deletes specified token -sub DeleteToken { +sub delete_token { my ($token) = @_; my $dbh = Bugzilla->dbh; @@ -300,6 +307,50 @@ sub DeleteToken { $dbh->bz_unlock_tables(); } +# Given a token, makes sure it comes from the currently logged in user +# and match the expected event. Returns 1 on success, else displays a warning. +# Note: this routine must not be called while tables are locked as it will try +# to lock some tables itself, see CleanTokenTable(). +sub check_token_data { + my ($token, $expected_action) = @_; + my $user = Bugzilla->user; + my $template = Bugzilla->template; + my $cgi = Bugzilla->cgi; + + my ($creator_id, $date, $token_action) = GetTokenData($token); + unless ($creator_id + && $creator_id == $user->id + && $token_action eq $expected_action) + { + # Something is going wrong. Ask confirmation before processing. + # It is possible that someone tried to trick an administrator. + # In this case, we want to know his name! + require Bugzilla::User; + + my $vars = {}; + $vars->{'abuser'} = Bugzilla::User->new($creator_id)->identity; + $vars->{'token_action'} = $token_action; + $vars->{'expected_action'} = $expected_action; + $vars->{'script_name'} = basename($0); + + # Now is a good time to remove old tokens from the DB. + CleanTokenTable(); + + # If no token was found, create a valid token for the given action. + unless ($creator_id) { + $token = issue_session_token($expected_action); + $cgi->param('token', $token); + } + + print $cgi->header(); + + $template->process('admin/confirm-action.html.tmpl', $vars) + || ThrowTemplateError($template->error()); + exit; + } + return 1; +} + ################################################################################ # Internal Functions ################################################################################ -- cgit v1.2.3-24-g4f1b