summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Bugzilla/Auth/Login/Cookie.pm6
-rw-r--r--Bugzilla/Constants.pm2
-rw-r--r--Bugzilla/Token.pm22
-rwxr-xr-xattachment.cgi19
-rw-r--r--docs/en/xml/Bugzilla-Guide.xml4
-rw-r--r--template/en/default/admin/flag-type/edit.html.tmpl6
-rw-r--r--template/en/default/filterexceptions.pl2
-rw-r--r--template/en/default/global/code-error.html.tmpl3
-rw-r--r--template/en/default/pages/release-notes.html.tmpl30
-rw-r--r--template/en/default/reports/report-table.html.tmpl38
-rwxr-xr-xtoken.cgi7
11 files changed, 98 insertions, 41 deletions
diff --git a/Bugzilla/Auth/Login/Cookie.pm b/Bugzilla/Auth/Login/Cookie.pm
index 88c48e236..4db486a8f 100644
--- a/Bugzilla/Auth/Login/Cookie.pm
+++ b/Bugzilla/Auth/Login/Cookie.pm
@@ -72,8 +72,8 @@ sub get_login_info {
trick_taint($login_cookie);
detaint_natural($user_id);
- my $is_valid =
- $dbh->selectrow_array('SELECT 1
+ my $db_cookie =
+ $dbh->selectrow_array('SELECT cookie
FROM logincookies
WHERE cookie = ?
AND userid = ?
@@ -81,7 +81,7 @@ sub get_login_info {
undef, ($login_cookie, $user_id, $ip_addr));
# If the cookie is valid, return a valid username.
- if ($is_valid) {
+ if (defined $db_cookie && $login_cookie eq $db_cookie) {
# If we logged in successfully, then update the lastused
# time on the login cookie
$dbh->do("UPDATE logincookies SET lastused = NOW()
diff --git a/Bugzilla/Constants.pm b/Bugzilla/Constants.pm
index 1f712f25d..ef3afeccb 100644
--- a/Bugzilla/Constants.pm
+++ b/Bugzilla/Constants.pm
@@ -209,7 +209,7 @@ use Memoize;
# CONSTANTS
#
# Bugzilla version
-use constant BUGZILLA_VERSION => "4.2.6+";
+use constant BUGZILLA_VERSION => "4.2.7";
# Location of the remote and local XML files to track new releases.
use constant REMOTE_FILE => 'http://updates.bugzilla.org/bugzilla-update.xml';
diff --git a/Bugzilla/Token.pm b/Bugzilla/Token.pm
index 4804851bb..24df470ac 100644
--- a/Bugzilla/Token.pm
+++ b/Bugzilla/Token.pm
@@ -277,13 +277,18 @@ sub Cancel {
# Get information about the token being canceled.
trick_taint($token);
- my ($issuedate, $tokentype, $eventdata, $userid) =
- $dbh->selectrow_array('SELECT ' . $dbh->sql_date_format('issuedate') . ',
+ my ($db_token, $issuedate, $tokentype, $eventdata, $userid) =
+ $dbh->selectrow_array('SELECT token, ' . $dbh->sql_date_format('issuedate') . ',
tokentype, eventdata, userid
FROM tokens
WHERE token = ?',
undef, $token);
+ # Some DBs such as MySQL are case-insensitive by default so we do
+ # a quick comparison to make sure the tokens are indeed the same.
+ (defined $db_token && $db_token eq $token)
+ || ThrowCodeError("cancel_token_does_not_exist");
+
# If we are canceling the creation of a new user account, then there
# is no entry in the 'profiles' table.
my $user = new Bugzilla::User($userid);
@@ -348,10 +353,17 @@ sub GetTokenData {
$token = clean_text($token);
trick_taint($token);
- return $dbh->selectrow_array(
- "SELECT userid, " . $dbh->sql_date_format('issuedate') . ", eventdata
- FROM tokens
+ my @token_data = $dbh->selectrow_array(
+ "SELECT token, userid, " . $dbh->sql_date_format('issuedate') . ", eventdata
+ FROM tokens
WHERE token = ?", undef, $token);
+
+ # Some DBs such as MySQL are case-insensitive by default so we do
+ # a quick comparison to make sure the tokens are indeed the same.
+ my $db_token = shift @token_data;
+ return undef if (!defined $db_token || $db_token ne $token);
+
+ return @token_data;
}
# Deletes specified token
diff --git a/attachment.cgi b/attachment.cgi
index 95d793e75..57706d5e0 100755
--- a/attachment.cgi
+++ b/attachment.cgi
@@ -680,20 +680,23 @@ sub update {
$attachment->set_filename(scalar $cgi->param('filename'));
# Now make sure the attachment has not been edited since we loaded the page.
- if (defined $cgi->param('delta_ts')
- && $cgi->param('delta_ts') ne $attachment->modification_time)
- {
- ($vars->{'operations'}) =
- Bugzilla::Bug::GetBugActivity($bug->id, $attachment->id, $cgi->param('delta_ts'));
+ my $delta_ts = $cgi->param('delta_ts');
+ my $modification_time = $attachment->modification_time;
- # The token contains the old modification_time. We need a new one.
- $cgi->param('token', issue_hash_token([$attachment->id, $attachment->modification_time]));
+ if ($delta_ts && $delta_ts ne $modification_time) {
+ datetime_from($delta_ts)
+ or ThrowCodeError('invalid_timestamp', { timestamp => $delta_ts });
+ ($vars->{'operations'}) =
+ Bugzilla::Bug::GetBugActivity($bug->id, $attachment->id, $delta_ts);
# If the modification date changed but there is no entry in
# the activity table, this means someone commented only.
# In this case, there is no reason to midair.
if (scalar(@{$vars->{'operations'}})) {
- $cgi->param('delta_ts', $attachment->modification_time);
+ $cgi->param('delta_ts', $modification_time);
+ # The token contains the old modification_time. We need a new one.
+ $cgi->param('token', issue_hash_token([$attachment->id, $modification_time]));
+
$vars->{'attachment'} = $attachment;
print $cgi->header();
diff --git a/docs/en/xml/Bugzilla-Guide.xml b/docs/en/xml/Bugzilla-Guide.xml
index 045a426ee..d2079630f 100644
--- a/docs/en/xml/Bugzilla-Guide.xml
+++ b/docs/en/xml/Bugzilla-Guide.xml
@@ -32,9 +32,9 @@
For a devel release, simple bump bz-ver and bz-date
-->
-<!ENTITY bz-ver "4.2.6">
+<!ENTITY bz-ver "4.2.7">
<!ENTITY bz-nextver "4.4">
-<!ENTITY bz-date "2013-05-22">
+<!ENTITY bz-date "2013-10-16">
<!ENTITY current-year "2013">
<!ENTITY landfillbase "http://landfill.bugzilla.org/bugzilla-4.2-branch/">
diff --git a/template/en/default/admin/flag-type/edit.html.tmpl b/template/en/default/admin/flag-type/edit.html.tmpl
index 46346d2ea..69dc05bd3 100644
--- a/template/en/default/admin/flag-type/edit.html.tmpl
+++ b/template/en/default/admin/flag-type/edit.html.tmpl
@@ -52,7 +52,7 @@
<form id="flagtype_properties" method="post" action="editflagtypes.cgi">
<input type="hidden" name="action" value="[% action FILTER html %]">
<input type="hidden" name="can_fully_edit" value="[% can_fully_edit FILTER html %]">
- <input type="hidden" name="id" value="[% type.id %]">
+ <input type="hidden" name="id" value="[% type.id FILTER html %]">
<input type="hidden" name="token" value="[% token FILTER html %]">
<input type="hidden" name="target_type" value="[% type.target_type FILTER html %]">
<input type="hidden" name="check_clusions" value="[% check_clusions FILTER none %]">
@@ -149,8 +149,8 @@
this type will be sorted when displayed to users in a list; ignore if you
don't care what order the types appear in or if you want them to appear
in alphabetical order.<br>
- <input type="text" name="sortkey" value="[% type.sortkey || 1 %]" size="5" maxlength="5"
- [%- ' disabled="disabled"' UNLESS can_fully_edit %]>
+ <input type="text" name="sortkey" value="[% type.sortkey || 1 FILTER html %]" size="5"
+ maxlength="5" [% ' disabled="disabled"' UNLESS can_fully_edit %]>
</td>
</tr>
diff --git a/template/en/default/filterexceptions.pl b/template/en/default/filterexceptions.pl
index 08757cfe7..16a3220e2 100644
--- a/template/en/default/filterexceptions.pl
+++ b/template/en/default/filterexceptions.pl
@@ -406,8 +406,6 @@
],
'admin/flag-type/edit.html.tmpl' => [
- 'type.id',
- 'type.sortkey || 1',
'selname',
],
diff --git a/template/en/default/global/code-error.html.tmpl b/template/en/default/global/code-error.html.tmpl
index d98f2578c..62442c268 100644
--- a/template/en/default/global/code-error.html.tmpl
+++ b/template/en/default/global/code-error.html.tmpl
@@ -438,6 +438,9 @@
[% ELSIF error == "token_generation_error" %]
Something is seriously wrong with the token generation system.
+ [% ELSIF error == "cancel_token_does_not_exist" %]
+ The token to be cancelled does not exist.
+
[% ELSIF error == "template_error" %]
[% template_error_msg FILTER html %]
diff --git a/template/en/default/pages/release-notes.html.tmpl b/template/en/default/pages/release-notes.html.tmpl
index 3d5b36b45..ebc08afb1 100644
--- a/template/en/default/pages/release-notes.html.tmpl
+++ b/template/en/default/pages/release-notes.html.tmpl
@@ -53,6 +53,36 @@
<h2 id="v42_point">Updates in this 4.2.x Release</h2>
+<h3>4.2.7</h3>
+
+<p>This release fixes several security issues. See the
+ <a href="http://www.bugzilla.org/security/4.0.10/">Security Advisory</a>
+ for details.</p>
+
+<p>In addition, the following [% terms.bugs %] have been fixed in this release:</p>
+
+<ul>
+ <li>Internet Explorer 11 and KHTML-based browsers such as Konqueror can now
+ display buglists correctly.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=902515">[% terms.Bug %] 902515</a> and
+ <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=914262">[% terms.bug %] 914262</a>)</li>
+ <li>When the <kbd>password_complexity</kbd> parameter was set to
+ 'letters_numbers_specialchars', passwords containing numbers and special
+ characters only were accepted. Now it makes sure that a letter is also present.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=897264">[% terms.Bug %] 897264</a>)</li>
+ <li>With DB servers doing case-insensitive comparisons, such as MySQL, tokens
+ and login cookies were not correctly validated as the case was ignored.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=906745">[% terms.Bug %] 906745</a> and
+ <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=907438">[% terms.bug %] 907438</a>)</li>
+ <li>All security headers (such as X-Frame-Options) are now returned when using XML-RPC.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=787328">[% terms.Bug %] 787328</a>)</li>
+ <li>Oracle crashed when reporting a new [% terms.bug %] if a custom free-text field
+ was non-mandatory and left empty.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=919475">[% terms.Bug %] 919475</a>)</li>
+ <li>It was not possible to import [% terms.bugs %] using <kbd>importxml.pl</kbd> with Oracle.
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=848063">[% terms.Bug %] 848063</a>)</li>
+</ul>
+
<h3>4.2.6</h3>
<p>The following important fixes/changes have been made in this release:</p>
diff --git a/template/en/default/reports/report-table.html.tmpl b/template/en/default/reports/report-table.html.tmpl
index b41753550..cef47c2d9 100644
--- a/template/en/default/reports/report-table.html.tmpl
+++ b/template/en/default/reports/report-table.html.tmpl
@@ -47,32 +47,42 @@
[% END %]
<script type="text/javascript">
+function bz_encode (str, decode) {
+ // First decode HTML entities, if requested.
+ if (decode)
+ str = str.replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"')
+ .replace(/&nbsp;/g, " ").replace(/&amp;/g, "&").replace(/\s+$/,"");
+
+ // encodeURIComponent() doesn't escape single quotes.
+ return encodeURIComponent(str).replace(/'/g, escape);
+};
+
YAHOO.util.Event.addListener(window, "load", function() {
this.Linkify = function(elLiner, oRecord, oColumn, oData) {
if (oData == 0)
elLiner.innerHTML = ".";
else if (oRecord.getData("row_title") == "Total")
- elLiner.innerHTML = "<a href='[% urlbase %]&amp;[% col_field FILTER js %]="
- + oColumn.field + "[% '&amp;' _ row_vals IF row_vals %]'>"
- + oData + "</a>";
+ elLiner.innerHTML = '<a href="[% urlbase FILTER js %]&amp;[% col_field FILTER uri FILTER js %]='
+ + bz_encode(oColumn.field)
+ + '[% "&amp;" _ row_vals IF row_vals %]">' + oData + '</a>';
else
- elLiner.innerHTML = "<a href='[% urlbase %]&amp;[% row_field FILTER js %]="
- + oRecord.getData("row_title").replace(/\s+$/,"")
- + "&amp;[% col_field FILTER js %]=" + oColumn.field
- + "'>" + oData + "</a>";
+ elLiner.innerHTML = '<a href="[% urlbase FILTER js %]&amp;[% row_field FILTER uri FILTER js %]='
+ + bz_encode(oRecord.getData("row_title"), 1)
+ + '&amp;[% col_field FILTER uri FILTER js %]='
+ + bz_encode(oColumn.field) + '">' + oData + '</a>';
};
this.LinkifyTotal = function(elLiner, oRecord, oColumn, oData) {
if (oData == 0)
elLiner.innerHTML = ".";
else if (oRecord.getData("row_title") == "Total")
- elLiner.innerHTML = "<a href='[% urlbase %][% '&amp;' _ row_vals IF row_vals %]
- [%~ '&amp;' _ col_vals IF col_vals %]'>"
- + oData + "</a>";
+ elLiner.innerHTML = '<a href="[% urlbase FILTER js %][% "&amp;" _ row_vals IF row_vals %]
+ [%~ "&amp;" _ col_vals IF col_vals %]">'
+ + oData + '</a>';
else
- elLiner.innerHTML = "<a href='[% urlbase %]&amp;[% row_field FILTER js %]="
- + oRecord.getData("row_title").replace(/\s+$/,"")
- + "[% '&amp;' _ col_vals IF col_vals %]'>" + oData + "</a>";
+ elLiner.innerHTML = '<a href="[% urlbase FILTER js %]&amp;[% row_field FILTER uri FILTER js %]='
+ + bz_encode(oRecord.getData("row_title"), 1)
+ + '[% "&amp;" _ col_vals IF col_vals %]">' + oData + '</a>';
YAHOO.util.Dom.addClass(elLiner.parentNode, "ttotal");
};
@@ -164,7 +174,7 @@ YAHOO.util.Event.addListener(window, "load", function() {
[% col_idx = 0 %]
[% row_idx = 0 %]
[% grand_total = 0 %]
-<div id="tabular_report_container_[% tbl FILTER js %]">
+<div id="tabular_report_container_[% tbl FILTER html %]">
<table id="tabular_report" border="1">
[% IF col_field %]
<thead>
diff --git a/token.cgi b/token.cgi
index 20870159a..901094be4 100755
--- a/token.cgi
+++ b/token.cgi
@@ -67,9 +67,10 @@ if ($token) {
trick_taint($token);
# Make sure the token exists in the database.
- my ($tokentype) = $dbh->selectrow_array('SELECT tokentype FROM tokens
- WHERE token = ?', undef, $token);
- $tokentype || ThrowUserError("token_does_not_exist");
+ my ($db_token, $tokentype) = $dbh->selectrow_array('SELECT token, tokentype FROM tokens
+ WHERE token = ?', undef, $token);
+ (defined $db_token && $db_token eq $token)
+ || ThrowUserError("token_does_not_exist");
# Make sure the token is the correct type for the action being taken.
if ( grep($action eq $_ , qw(cfmpw cxlpw chgpw)) && $tokentype ne 'password' ) {