Commit d3829921 authored by lpsolit%gmail.com's avatar lpsolit%gmail.com

Bug 466692: [SECURITY] keywords and unused flag types can be deleted by…

Bug 466692: [SECURITY] keywords and unused flag types can be deleted by bypassing the token check - Patch by Fré©ric Buclin <LpSolit@gmail.com> r=mkanat a=LpSolit
parent 44341577
...@@ -80,7 +80,7 @@ elsif ($action eq 'edit') { edit($action); } ...@@ -80,7 +80,7 @@ elsif ($action eq 'edit') { edit($action); }
elsif ($action eq 'insert') { insert($token); } elsif ($action eq 'insert') { insert($token); }
elsif ($action eq 'update') { update($token); } elsif ($action eq 'update') { update($token); }
elsif ($action eq 'confirmdelete') { confirmDelete(); } elsif ($action eq 'confirmdelete') { confirmDelete(); }
elsif ($action eq 'delete') { deleteType(undef, $token); } elsif ($action eq 'delete') { deleteType($token); }
elsif ($action eq 'deactivate') { deactivate($token); } elsif ($action eq 'deactivate') { deactivate($token); }
else { else {
ThrowCodeError("action_unrecognized", { action => $action }); ThrowCodeError("action_unrecognized", { action => $action });
...@@ -460,9 +460,8 @@ sub update { ...@@ -460,9 +460,8 @@ sub update {
sub confirmDelete { sub confirmDelete {
my $flag_type = validateID(); my $flag_type = validateID();
if ($flag_type->flag_count) {
$vars->{'flag_type'} = $flag_type; $vars->{'flag_type'} = $flag_type;
$vars->{'token'} = issue_session_token('delete_flagtype'); $vars->{'token'} = issue_session_token('delete_flagtype');
# Return the appropriate HTTP response headers. # Return the appropriate HTTP response headers.
...@@ -471,20 +470,13 @@ sub confirmDelete { ...@@ -471,20 +470,13 @@ sub confirmDelete {
# Generate and return the UI (HTML page) from the appropriate template. # Generate and return the UI (HTML page) from the appropriate template.
$template->process("admin/flag-type/confirm-delete.html.tmpl", $vars) $template->process("admin/flag-type/confirm-delete.html.tmpl", $vars)
|| ThrowTemplateError($template->error()); || ThrowTemplateError($template->error());
}
else {
# We should *always* ask if the admin really wants to delete
# a flagtype, even if there is no flag belonging to this type.
my $token = issue_session_token('delete_flagtype');
deleteType($flag_type, $token);
}
} }
sub deleteType { sub deleteType {
my $flag_type = shift || validateID();
my $token = shift; my $token = shift;
check_token_data($token, 'delete_flagtype'); check_token_data($token, 'delete_flagtype');
my $flag_type = validateID();
my $id = $flag_type->id; my $id = $flag_type->id;
my $dbh = Bugzilla->dbh; my $dbh = Bugzilla->dbh;
......
...@@ -151,26 +151,23 @@ if ($action eq 'update') { ...@@ -151,26 +151,23 @@ if ($action eq 'update') {
exit; exit;
} }
if ($action eq 'del') {
if ($action eq 'delete') {
my $keyword = new Bugzilla::Keyword($key_id) my $keyword = new Bugzilla::Keyword($key_id)
|| ThrowCodeError('invalid_keyword_id', { id => $key_id }); || ThrowCodeError('invalid_keyword_id', { id => $key_id });
$vars->{'keyword'} = $keyword; $vars->{'keyword'} = $keyword;
$vars->{'token'} = issue_session_token('delete_keyword');
# We need this token even if there is no bug using this keyword. print $cgi->header();
$token = issue_session_token('delete_keyword'); $template->process("admin/keywords/confirm-delete.html.tmpl", $vars)
|| ThrowTemplateError($template->error());
if (!$cgi->param('reallydelete') && $keyword->bug_count) { exit;
$vars->{'token'} = $token; }
print $cgi->header(); if ($action eq 'delete') {
$template->process("admin/keywords/confirm-delete.html.tmpl", $vars)
|| ThrowTemplateError($template->error());
exit;
}
# We cannot do this check earlier as we have to check 'reallydelete' first.
check_token_data($token, 'delete_keyword'); check_token_data($token, 'delete_keyword');
my $keyword = new Bugzilla::Keyword($key_id)
|| ThrowCodeError('invalid_keyword_id', { id => $key_id });
$dbh->do('DELETE FROM keywords WHERE keywordid = ?', undef, $keyword->id); $dbh->do('DELETE FROM keywords WHERE keywordid = ?', undef, $keyword->id);
$dbh->do('DELETE FROM keyworddefs WHERE id = ?', undef, $keyword->id); $dbh->do('DELETE FROM keyworddefs WHERE id = ?', undef, $keyword->id);
......
...@@ -28,13 +28,16 @@ ...@@ -28,13 +28,16 @@
%] %]
<p> <p>
There are [% flag_type.flag_count %] flags of type [% flag_type.name FILTER html %]. [% IF flag_type.flag_count %]
If you delete this type, those flags will also be deleted. Note that There are [% flag_type.flag_count %] flags of type [% flag_type.name FILTER html %].
instead of deleting the type you can If you delete this type, those flags will also be deleted.
[% END %]
Note that instead of deleting the type you can
<a href="editflagtypes.cgi?action=deactivate&amp;id=[% flag_type.id %]&amp;token= <a href="editflagtypes.cgi?action=deactivate&amp;id=[% flag_type.id %]&amp;token=
[%- token FILTER html %]">deactivate it</a>, [%- token FILTER html %]">deactivate it</a>,
in which case the type and its flags will remain in the database in which case the type [% IF flag_type.flag_count %] and its flags [% END %] will remain
but will not appear in the [% terms.Bugzilla %] UI. in the database but will not appear in the [% terms.Bugzilla %] UI.
</p> </p>
<table> <table>
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
<p> <p>
[% IF keyword.bug_count == 1 %] [% IF keyword.bug_count == 1 %]
There is one [% terms.bug %] with this keyword set. There is one [% terms.bug %] with this keyword set.
[% ELSE %] [% ELSIF keyword.bug_count > 1 %]
There are [% keyword.bug_count FILTER html %] [%+ terms.bugs %] with There are [% keyword.bug_count FILTER html %] [%+ terms.bugs %] with
this keyword set. this keyword set.
[% END %] [% END %]
...@@ -43,7 +43,6 @@ ...@@ -43,7 +43,6 @@
<form method="post" action="editkeywords.cgi"> <form method="post" action="editkeywords.cgi">
<input type="hidden" name="id" value="[% keyword.id FILTER html %]"> <input type="hidden" name="id" value="[% keyword.id FILTER html %]">
<input type="hidden" name="action" value="delete"> <input type="hidden" name="action" value="delete">
<input type="hidden" name="reallydelete" value="1">
<input type="hidden" name="token" value="[% token FILTER html %]"> <input type="hidden" name="token" value="[% token FILTER html %]">
<input type="submit" id="delete" <input type="submit" id="delete"
value="Yes, really delete the keyword"> value="Yes, really delete the keyword">
......
...@@ -54,7 +54,7 @@ ...@@ -54,7 +54,7 @@
{ {
heading => "Action" heading => "Action"
content => "Delete" content => "Delete"
contentlink => "editkeywords.cgi?action=delete&amp;id=%%id%%" contentlink => "editkeywords.cgi?action=del&amp;id=%%id%%"
} }
] ]
%] %]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment