summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDylan William Hardison <dylan@hardison.net>2017-01-25 21:04:07 +0100
committerDylan William Hardison <dylan@hardison.net>2017-01-25 21:04:21 +0100
commit6a727b70a9f7d3deb690dffd818d7bb5e9eb7bf5 (patch)
tree28aea39d85e63a901744c6319f6dc06884040daf
parentec963661fb29c191fec645a956cbddc670cfa3da (diff)
downloadbugzilla-6a727b70a9f7d3deb690dffd818d7bb5e9eb7bf5.tar.gz
bugzilla-6a727b70a9f7d3deb690dffd818d7bb5e9eb7bf5.tar.xz
Bug 1286290 - CSP compliant bug modal
-rw-r--r--Bugzilla.pm7
-rw-r--r--Bugzilla/CGI.pm46
-rw-r--r--Bugzilla/CGI/ContentSecurityPolicy.pm1
-rw-r--r--Bugzilla/Template.pm5
-rwxr-xr-xattachment.cgi28
-rw-r--r--extensions/BMO/template/en/default/hook/bug_modal/edit-top_actions.html.tmpl4
-rw-r--r--extensions/BMO/web/js/edituser_menu.js6
-rw-r--r--extensions/BugModal/template/en/default/bug_modal/edit.html.tmpl2
-rw-r--r--extensions/BugModal/template/en/default/bug_modal/user.html.tmpl7
-rw-r--r--extensions/BugModal/web/bug_modal.js7
-rw-r--r--extensions/GitHubAuth/template/en/default/hook/account/auth/login-small-additional_methods.html.tmpl2
-rw-r--r--extensions/Needinfo/template/en/default/bug/needinfo.html.tmpl11
-rw-r--r--extensions/Persona/template/en/default/hook/account/auth/login-additional_methods.html.tmpl2
-rw-r--r--extensions/Persona/template/en/default/hook/account/auth/login-small-additional_methods.html.tmpl4
-rw-r--r--extensions/Persona/template/en/default/hook/account/create-additional_methods.html.tmpl2
-rw-r--r--extensions/Persona/template/en/default/hook/global/header-additional_header.html.tmpl7
-rwxr-xr-xindex.cgi2
-rw-r--r--js/global.js26
-rwxr-xr-xpost_bug.cgi3
-rwxr-xr-xprocess_bug.cgi8
-rwxr-xr-xshow_bug.cgi5
-rw-r--r--template/en/default/account/auth/login-small.html.tmpl12
-rw-r--r--template/en/default/bug/process/bugmail.html.tmpl37
-rw-r--r--template/en/default/global/common-links.html.tmpl4
-rw-r--r--template/en/default/global/header.html.tmpl14
-rw-r--r--template/en/default/global/per-bug-queries.html.tmpl11
-rw-r--r--template/en/default/global/userselect.html.tmpl5
-rw-r--r--template/en/default/index.html.tmpl10
-rw-r--r--template/en/default/pages/quicksearch.html.tmpl4
29 files changed, 208 insertions, 74 deletions
diff --git a/Bugzilla.pm b/Bugzilla.pm
index f563ba9e3..55e416933 100644
--- a/Bugzilla.pm
+++ b/Bugzilla.pm
@@ -210,10 +210,13 @@ sub init_page {
sub template {
# BMO - use metrics subclass if required
if (Bugzilla->metrics_enabled) {
- return $_[0]->request_cache->{template} ||= Bugzilla::Metrics::Template->create();
+ $_[0]->request_cache->{template} ||= Bugzilla::Metrics::Template->create();
} else {
- return $_[0]->request_cache->{template} ||= Bugzilla::Template->create();
+ $_[0]->request_cache->{template} ||= Bugzilla::Template->create();
}
+ $_[0]->request_cache->{template}->{_is_main} = 1;
+
+ return $_[0]->request_cache->{template};
}
sub template_inner {
diff --git a/Bugzilla/CGI.pm b/Bugzilla/CGI.pm
index 78987ab71..91dec7e72 100644
--- a/Bugzilla/CGI.pm
+++ b/Bugzilla/CGI.pm
@@ -33,13 +33,41 @@ BEGIN {
use constant DEFAULT_CSP => (
default_src => [ 'self' ],
- script_src => [ 'self', 'https://login.persona.org', 'unsafe-inline', 'unsafe-eval' ],
- child_src => [ 'self', 'https://login.persona.org' ],
+ script_src => [ 'self', 'unsafe-inline', 'unsafe-eval' ],
+ child_src => [ 'self', ],
img_src => [ 'self', 'https://secure.gravatar.com' ],
style_src => [ 'self', 'unsafe-inline' ],
- disable => 1,
+ object_src => [ 'none' ],
+ form_action => [
+ 'self',
+ # used in template/en/default/search/search-google.html.tmpl
+ 'https://www.google.com/search'
+ ],
+ frame_ancestors => [ 'none' ],
+ disable => 1,
);
+# Because show_bug code lives in many different .cgi files,
+# we needed a centralized place to define the policy.
+# normally the policy would just live in one .cgi file.
+# Additionally, correct_urlbase() cannot be called at compile time, so this can't be a constant.
+sub SHOW_BUG_MODAL_CSP {
+ return (
+ script_src => ['self', 'nonce', 'unsafe-inline', 'unsafe-eval' ],
+ object_src => [correct_urlbase() . "extensions/BugModal/web/ZeroClipboard/ZeroClipboard.swf"],
+ connect_src => [
+ 'self',
+ # This is from extensions/OrangeFactor/web/js/orange_factor.js
+ 'https://brasstacks.mozilla.com/orangefactor/api/count',
+ ],
+ child_src => [
+ 'self',
+ # This is for the socorro lens addon and is to be removed by Bug 1332016
+ 'https://ashughes1.github.io/bugzilla-socorro-lens/chart.htm'
+ ],
+ );
+}
+
sub _init_bz_cgi_globals {
my $invocant = shift;
# We need to disable output buffering - see bug 179174
@@ -143,9 +171,9 @@ sub content_security_policy {
my ($self, %add_params) = @_;
if (Bugzilla->has_feature('csp')) {
require Bugzilla::CGI::ContentSecurityPolicy;
- return $self->{Bugzilla_csp} if $self->{Bugzilla_csp};
- my %params = DEFAULT_CSP;
- if (%add_params) {
+ if (%add_params || !$self->{Bugzilla_csp}) {
+ my %params = DEFAULT_CSP;
+ delete $params{disable} if %add_params && !$add_params{disable};
foreach my $key (keys %add_params) {
if (defined $add_params{$key}) {
$params{$key} = $add_params{$key};
@@ -154,8 +182,10 @@ sub content_security_policy {
delete $params{$key};
}
}
+ $self->{Bugzilla_csp} = Bugzilla::CGI::ContentSecurityPolicy->new(%params);
}
- return $self->{Bugzilla_csp} = Bugzilla::CGI::ContentSecurityPolicy->new(%params);
+
+ return $self->{Bugzilla_csp};
}
return undef;
}
@@ -455,7 +485,7 @@ sub header {
$headers{'-x_content_type_options'} = 'nosniff';
my $csp = $self->content_security_policy;
- $csp->add_cgi_headers(\%headers) if defined $csp;
+ $csp->add_cgi_headers(\%headers) if defined $csp && !$csp->disable;
Bugzilla::Hook::process('cgi_headers',
{ cgi => $self, headers => \%headers }
diff --git a/Bugzilla/CGI/ContentSecurityPolicy.pm b/Bugzilla/CGI/ContentSecurityPolicy.pm
index 74bce6374..022d49b44 100644
--- a/Bugzilla/CGI/ContentSecurityPolicy.pm
+++ b/Bugzilla/CGI/ContentSecurityPolicy.pm
@@ -37,6 +37,7 @@ my @ALL_SRC = qw(
default_src child_src connect_src
font_src img_src media_src
object_src script_src style_src
+ frame_ancestors form_action
);
has \@ALL_SRC => ( is => 'ro', isa => $SOURCE_LIST, predicate => 1 );
diff --git a/Bugzilla/Template.pm b/Bugzilla/Template.pm
index eb1496fca..2887f0138 100644
--- a/Bugzilla/Template.pm
+++ b/Bugzilla/Template.pm
@@ -1000,6 +1000,11 @@ sub create {
# Currenly active language
'current_language' => sub { return Bugzilla->current_language; },
+ 'script_nonce' => sub {
+ my $cgi = Bugzilla->cgi;
+ return $cgi->csp_nonce ? sprintf('nonce="%s"', $cgi->csp_nonce) : '';
+ },
+
# If an sudo session is in progress, this is the user who
# started the session.
'sudoer' => sub { return Bugzilla->sudoer; },
diff --git a/attachment.cgi b/attachment.cgi
index d5a69f198..d228c9c7f 100755
--- a/attachment.cgi
+++ b/attachment.cgi
@@ -628,6 +628,14 @@ sub insert {
my $recipients = { 'changer' => $user, 'owner' => $owner };
$vars->{'sent_bugmail'} = Bugzilla::BugMail::Send($bugid, $recipients);
+ # BMO: add show_bug_format hook for experimental UI work
+ my $show_bug_format = {};
+ Bugzilla::Hook::process('show_bug_format', $show_bug_format);
+
+ if ($show_bug_format->{format} eq 'modal') {
+ $cgi->content_security_policy(Bugzilla::CGI::SHOW_BUG_MODAL_CSP());
+ }
+
print $cgi->header();
# Generate and return the UI (HTML page) from the appropriate template.
$template->process("attachment/created.html.tmpl", $vars)
@@ -784,6 +792,14 @@ sub update {
$vars->{'sent_bugmail'} =
Bugzilla::BugMail::Send($bug->id, { 'changer' => $user });
+ # BMO: add show_bug_format hook for experimental UI work
+ my $show_bug_format = {};
+ Bugzilla::Hook::process('show_bug_format', $show_bug_format);
+
+ if ($show_bug_format->{format} eq 'modal') {
+ $cgi->content_security_policy(Bugzilla::CGI::SHOW_BUG_MODAL_CSP());
+ }
+
print $cgi->header();
# Generate and return the UI (HTML page) from the appropriate template.
@@ -796,8 +812,6 @@ sub delete_attachment {
my $user = Bugzilla->login(LOGIN_REQUIRED);
my $dbh = Bugzilla->dbh;
- print $cgi->header();
-
$user->in_group('admin')
|| ThrowUserError('auth_failure', {group => 'admin',
action => 'delete',
@@ -853,6 +867,15 @@ sub delete_attachment {
$vars->{'sent_bugmail'} =
Bugzilla::BugMail::Send($bug->id, { 'changer' => $user });
+ # BMO: add show_bug_format hook for experimental UI work
+ my $show_bug_format = {};
+ Bugzilla::Hook::process('show_bug_format', $show_bug_format);
+
+ if ($show_bug_format->{format} eq 'modal') {
+ $cgi->content_security_policy(Bugzilla::CGI::SHOW_BUG_MODAL_CSP());
+ }
+
+ print $cgi->header();
$template->process("attachment/updated.html.tmpl", $vars)
|| ThrowTemplateError($template->error());
}
@@ -863,6 +886,7 @@ sub delete_attachment {
$vars->{'a'} = $attachment;
$vars->{'token'} = $token;
+ print $cgi->header();
$template->process("attachment/confirm-delete.html.tmpl", $vars)
|| ThrowTemplateError($template->error());
}
diff --git a/extensions/BMO/template/en/default/hook/bug_modal/edit-top_actions.html.tmpl b/extensions/BMO/template/en/default/hook/bug_modal/edit-top_actions.html.tmpl
index 03c7d2e49..a21e8a441 100644
--- a/extensions/BMO/template/en/default/hook/bug_modal/edit-top_actions.html.tmpl
+++ b/extensions/BMO/template/en/default/hook/bug_modal/edit-top_actions.html.tmpl
@@ -16,7 +16,7 @@
END;
END;
%]
-<button type="button" class="minor"
- onclick="document.location='page.cgi?id=attachment_bounty_form.html&amp;bug_id=[% bug.id FILTER none %]'">
+<button type="button" class="minor button-link"
+ data-href="page.cgi?id=attachment_bounty_form.html&amp;bug_id=[% bug.id FILTER none %]">
[% has_bounty_attachment ? "Edit" : "Add" %] Bounty Tracking Attachment
</button>
diff --git a/extensions/BMO/web/js/edituser_menu.js b/extensions/BMO/web/js/edituser_menu.js
index 707e35b6e..7008a2b84 100644
--- a/extensions/BMO/web/js/edituser_menu.js
+++ b/extensions/BMO/web/js/edituser_menu.js
@@ -45,3 +45,9 @@ function show_usermenu(id, email, show_edit) {
});
}
+$(function() {
+ $('.show_usermenu').on("click", function (event) {
+ var $this = $(this);
+ return show_usermenu($this.data('user-id'), $this.data('user-email'), $this.data('show-edit'));
+ });
+});
diff --git a/extensions/BugModal/template/en/default/bug_modal/edit.html.tmpl b/extensions/BugModal/template/en/default/bug_modal/edit.html.tmpl
index fe0a7d4fe..acdd55ee2 100644
--- a/extensions/BugModal/template/en/default/bug_modal/edit.html.tmpl
+++ b/extensions/BugModal/template/en/default/bug_modal/edit.html.tmpl
@@ -1194,7 +1194,7 @@
[%# === initialise module visibility === %]
-<script>
+<script [% script_nonce FILTER none %]>
init_module_visibility();
</script>
diff --git a/extensions/BugModal/template/en/default/bug_modal/user.html.tmpl b/extensions/BugModal/template/en/default/bug_modal/user.html.tmpl
index 4c28936cc..5c630ba07 100644
--- a/extensions/BugModal/template/en/default/bug_modal/user.html.tmpl
+++ b/extensions/BugModal/template/en/default/bug_modal/user.html.tmpl
@@ -41,11 +41,12 @@ END;
width="[% gravatar_size FILTER none %]" height="[% gravatar_size FILTER none %]">
[% END %]
[% UNLESS gravatar_only %]
- <a class="email [%= "disabled" UNLESS u.is_enabled %]"
+ <a class="email [%= "disabled" UNLESS u.is_enabled %] [%= "show_usermenu" IF user.id %]"
[% IF user.id %]
href="mailto:[% u.email FILTER html %]"
- onclick="return show_usermenu([% u.id FILTER none %], '[% u.email FILTER js %]',
- [% user.in_group('editusers') || user.bless_groups.size > 0 ? "true" : "false" %])"
+ data-user-id="[% u.id FILTER html %]"
+ data-user-email="[% u.email FILTER html %]"
+ data-show-edit="[% user.in_group('editusers') || user.bless_groups.size > 9 ? 'true' : 'false' %]"
title="[% u.identity FILTER html %]"
[% ELSE %]
href="user_profile?user_id=[% u.id FILTER none %]"
diff --git a/extensions/BugModal/web/bug_modal.js b/extensions/BugModal/web/bug_modal.js
index d77821929..01be1fd2c 100644
--- a/extensions/BugModal/web/bug_modal.js
+++ b/extensions/BugModal/web/bug_modal.js
@@ -1483,6 +1483,13 @@ function lb_close(event) {
$('#lb_overlay, #lb_overlay2, #lb_close_btn, #lb_img, #lb_text').remove();
}
+$(function() {
+ $("button.button-link").on("click", function (event) {
+ event.preventDefault();
+ window.location = $(this).data("href");
+ });
+});
+
// extensions
(function($) {
diff --git a/extensions/GitHubAuth/template/en/default/hook/account/auth/login-small-additional_methods.html.tmpl b/extensions/GitHubAuth/template/en/default/hook/account/auth/login-small-additional_methods.html.tmpl
index adcd9e067..801d3d5fa 100644
--- a/extensions/GitHubAuth/template/en/default/hook/account/auth/login-small-additional_methods.html.tmpl
+++ b/extensions/GitHubAuth/template/en/default/hook/account/auth/login-small-additional_methods.html.tmpl
@@ -8,7 +8,7 @@
[% USE Bugzilla %]
[% IF Param('user_info_class').split(',').contains('GitHubAuth') %]
- <script type="text/javascript">
+ <script [% script_nonce FILTER none %] type="text/javascript">
YAHOO.util.Event.addListener('login_link[% qs_suffix FILTER js %]','click', function () {
var login_link = YAHOO.util.Dom.get('github_mini_login[% qs_suffix FILTER js %]');
YAHOO.util.Dom.removeClass(login_link, 'bz_default_hidden');
diff --git a/extensions/Needinfo/template/en/default/bug/needinfo.html.tmpl b/extensions/Needinfo/template/en/default/bug/needinfo.html.tmpl
index 4d2a39f38..915379316 100644
--- a/extensions/Needinfo/template/en/default/bug/needinfo.html.tmpl
+++ b/extensions/Needinfo/template/en/default/bug/needinfo.html.tmpl
@@ -39,7 +39,7 @@
RETURN UNLESS needinfo_flagtype;
%]
-<script>
+<script [% script_nonce FILTER none%]>
[% IF needinfo_flags.size > 0 %]
$(function() {
[%# Displays NEEDINFO tag in bug header %]
@@ -139,12 +139,11 @@ $(function() {
$('#needinfo').change();
}
- function needinfo_from_changed() {
- $('#needinfo').prop('checked', $('#needinfo_from').val() !== '');
- }
-
$(function() {
needinfo_init();
+ $(".needinfo_from_changed").on("change", function (event) {
+ $("#needinfo").prop("checked", $("#needinfo_from").val() !== '');
+ });
});
[% END %]
</script>
@@ -227,7 +226,7 @@ $(function() {
value => ""
size => 30
multiple => 5
- onchange => "needinfo_from_changed()"
+ classes => ["needinfo_from_changed"]
field_title => "Enter one or more comma separated users to request more information from"
%]
</span>
diff --git a/extensions/Persona/template/en/default/hook/account/auth/login-additional_methods.html.tmpl b/extensions/Persona/template/en/default/hook/account/auth/login-additional_methods.html.tmpl
index c964f9fed..1743db9a6 100644
--- a/extensions/Persona/template/en/default/hook/account/auth/login-additional_methods.html.tmpl
+++ b/extensions/Persona/template/en/default/hook/account/auth/login-additional_methods.html.tmpl
@@ -1,7 +1,7 @@
[% IF Param('user_info_class').split(',').contains('Persona')
&& Param('persona_includejs_url') %]
<p>
- <img src="extensions/Persona/web/images/persona_sign_in.png" width="185" height="25" onclick="persona_sign_in()">
+ <img src="extensions/Persona/web/images/persona_sign_in.png" width="185" height="25" class="persona_sign_in">
</p>
<p>
<strong>Note:</strong> Persona authentication will be removed on October 25th, 2016 (<a href="page.cgi?id=persona_deprecated.html">more info</a>).
diff --git a/extensions/Persona/template/en/default/hook/account/auth/login-small-additional_methods.html.tmpl b/extensions/Persona/template/en/default/hook/account/auth/login-small-additional_methods.html.tmpl
index 5d8503d73..17a86a71d 100644
--- a/extensions/Persona/template/en/default/hook/account/auth/login-small-additional_methods.html.tmpl
+++ b/extensions/Persona/template/en/default/hook/account/auth/login-small-additional_methods.html.tmpl
@@ -1,6 +1,6 @@
[% IF Param('user_info_class').split(',').contains('Persona')
&& Param('persona_includejs_url') %]
-<script type="text/javascript">
+<script [% script_nonce FILTER none %] type="text/javascript">
YAHOO.util.Event.addListener('login_link[% qs_suffix FILTER js %]','click', function () {
var login_link = YAHOO.util.Dom.get('persona_mini_login[% qs_suffix FILTER js %]');
YAHOO.util.Dom.removeClass(login_link, 'bz_default_hidden');
@@ -12,6 +12,6 @@
</script>
<span id="persona_mini_login[% qs_suffix FILTER html %]" class="bz_default_hidden">
<img src="extensions/Persona/web/images/sign_in.png" height="22" width="75" align="absmiddle"
- title="Sign in with Persona" onclick="persona_sign_in()"> or
+ title="Sign in with Persona" class='persona_sign_in'> or
</span>
[% END %]
diff --git a/extensions/Persona/template/en/default/hook/account/create-additional_methods.html.tmpl b/extensions/Persona/template/en/default/hook/account/create-additional_methods.html.tmpl
index 355ce3629..b6fb1eedc 100644
--- a/extensions/Persona/template/en/default/hook/account/create-additional_methods.html.tmpl
+++ b/extensions/Persona/template/en/default/hook/account/create-additional_methods.html.tmpl
@@ -9,5 +9,5 @@
[% RETURN UNLESS Param('user_info_class').split(',').contains('Persona') %]
Or, use your Persona account:
-<img src="extensions/Persona/web/images/sign_in.png" onclick="persona_sign_in()"
+<img src="extensions/Persona/web/images/sign_in.png" class="persona_sign_in"
width="95" height="25" align="absmiddle">
diff --git a/extensions/Persona/template/en/default/hook/global/header-additional_header.html.tmpl b/extensions/Persona/template/en/default/hook/global/header-additional_header.html.tmpl
index 5b2fa043b..12282df16 100644
--- a/extensions/Persona/template/en/default/hook/global/header-additional_header.html.tmpl
+++ b/extensions/Persona/template/en/default/hook/global/header-additional_header.html.tmpl
@@ -17,8 +17,8 @@
[% USE Bugzilla %]
[% cgi = Bugzilla.cgi %]
-<script defer src="[% Param('persona_includejs_url') %]" type="text/javascript"></script>
-<script type="text/javascript">
+<script [% script_nonce FILTER none %] defer src="[% Param('persona_includejs_url') %]" type="text/javascript"></script>
+<script [% script_nonce FILTER none %] type="text/javascript">
function createHidden(name, value, form) {
var field = document.createElement('input');
@@ -84,4 +84,7 @@ function persona_sign_in() {
persona_ignore_login = false;
navigator.id.request({ siteName: '[% terms.BugzillaTitle FILTER js %]' });
}
+$(function() {
+ $('.persona_sign_in').on("click", persona_sign_in);
+});
</script>
diff --git a/index.cgi b/index.cgi
index 1dd62d9fb..56513aff7 100755
--- a/index.cgi
+++ b/index.cgi
@@ -33,6 +33,8 @@ if ($cgi->param('logout')) {
$cgi->delete('logout');
}
+$cgi->content_security_policy(script_src => ['self', 'nonce']);
+
###############################################################################
# Main Body Execution
###############################################################################
diff --git a/js/global.js b/js/global.js
index 8ff509289..a997821f4 100644
--- a/js/global.js
+++ b/js/global.js
@@ -16,6 +16,31 @@
*
*/
+$(function () {
+ $('.show_mini_login_form').on("click", function (event) {
+ return show_mini_login_form($(this).data('qs-suffix'));
+ });
+ $('.hide_mini_login_form').on("click", function (event) {
+ return hide_mini_login_form($(this).data('qs-suffix'));
+ });
+ $('.show_forgot_form').on("click", function (event) {
+ return show_forgot_form($(this).data('qs-suffix'));
+ });
+ $('.hide_forgot_form').on("click", function (event) {
+ return hide_forgot_form($(this).data('qs-suffix'));
+ });
+ $('.check_mini_login_fields').on("click", function (event) {
+ return check_mini_login_fields($(this).data('qs-suffix'));
+ });
+ $('form .quicksearch_check_empty').on("submit", function (event) {
+ if (this.quicksearch.value == '') {
+ alert('Please enter one or more search terms first.');
+ return false;
+ }
+ return true;
+ });
+});
+
function show_mini_login_form( suffix ) {
$('#login_link' + suffix).addClass('bz_default_hidden');
$('#mini_login' + suffix).removeClass('bz_default_hidden');
@@ -37,6 +62,7 @@ function show_forgot_form( suffix ) {
return false;
}
+
function hide_forgot_form( suffix ) {
$('#forgot_link' + suffix).removeClass('bz_default_hidden');
$('#forgot_form' + suffix).addClass('bz_default_hidden');
diff --git a/post_bug.cgi b/post_bug.cgi
index 0975e32ae..bbba125c1 100755
--- a/post_bug.cgi
+++ b/post_bug.cgi
@@ -264,6 +264,9 @@ $format = $template->get_format("bug/create/created",
# don't leak the enter_bug format param to show_bug
$cgi->delete('format');
+if ($user->setting('ui_experiments') eq 'on') {
+ Bugzilla->cgi->content_security_policy(Bugzilla::CGI::SHOW_BUG_MODAL_CSP());
+}
print $cgi->header();
$template->process($format->{'template'}, $vars)
|| ThrowTemplateError($template->error());
diff --git a/process_bug.cgi b/process_bug.cgi
index 0858a3ff8..ac8e32c53 100755
--- a/process_bug.cgi
+++ b/process_bug.cgi
@@ -419,9 +419,12 @@ my $format_params = {
ctype => scalar $cgi->param('ctype'),
};
Bugzilla::Hook::process('show_bug_format', $format_params);
+if ($format_params->{format} eq 'modal') {
+ $cgi->content_security_policy(Bugzilla::CGI::SHOW_BUG_MODAL_CSP());
+}
my $format = $template->get_format("bug/show",
- $format_params->{format},
- $format_params->{ctype});
+ $format_params->{format},
+ $format_params->{ctype});
if (Bugzilla->usage_mode != USAGE_MODE_EMAIL) {
print $cgi->header();
@@ -466,5 +469,4 @@ if (Bugzilla->usage_mode != USAGE_MODE_EMAIL) {
$template->process("global/footer.html.tmpl", $vars)
|| ThrowTemplateError($template->error());
}
-
1;
diff --git a/show_bug.cgi b/show_bug.cgi
index 517017688..d4e6ea771 100755
--- a/show_bug.cgi
+++ b/show_bug.cgi
@@ -19,6 +19,7 @@ use Bugzilla::User;
use Bugzilla::Keyword;
use Bugzilla::Bug;
use Bugzilla::Hook;
+use Bugzilla::CGI;
my $cgi = Bugzilla->cgi;
my $template = Bugzilla->template;
@@ -36,6 +37,10 @@ my $format = $template->get_format("bug/show",
$format_params->{format},
$format_params->{ctype});
+if ($format_params->{format} eq 'modal') {
+ $cgi->content_security_policy(Bugzilla::CGI::SHOW_BUG_MODAL_CSP());
+}
+
# Editable, 'single' HTML bugs are treated slightly specially in a few places
my $single = (!$format->{format} || $format->{format} ne 'multiple')
&& $format->{extension} eq 'html';
diff --git a/template/en/default/account/auth/login-small.html.tmpl b/template/en/default/account/auth/login-small.html.tmpl
index 111aca0dd..b182ddef3 100644
--- a/template/en/default/account/auth/login-small.html.tmpl
+++ b/template/en/default/account/auth/login-small.html.tmpl
@@ -38,14 +38,15 @@
[% END %]
[% script_url = login_target _ connector _ "GoAheadAndLogIn=1" %]
<a id="login_link[% qs_suffix %]" href="[% script_url FILTER html %]"
- onclick="return show_mini_login_form('[% qs_suffix %]')">Log In</a>
+ class='show_mini_login_form' data-qs-suffix="[% qs_suffix FILTER html %]">Log In</a>
[% Hook.process('additional_methods') %]
<form action="[% login_target FILTER html %]" method="POST"
class="mini_login bz_default_hidden"
id="mini_login[% qs_suffix FILTER html %]"
- onsubmit="return check_mini_login_fields( '[% qs_suffix FILTER html %]' );"
+ class="check_mini_login_fields"
+ data-qs-suffix="[% qs_suffix FILTER html %]"
>
<input id="Bugzilla_login[% qs_suffix FILTER html %]"
@@ -77,13 +78,14 @@
<input type="submit" name="GoAheadAndLogIn" value="Log in"
id="log_in[% qs_suffix %]">
<a href="#" id="hide_mini_login[% qs_suffix FILTER html %]"
- onclick="return hide_mini_login_form('[% qs_suffix %]')">[x]</a>
+ class="hide_mini_login_form" data-qs-suffix="[% qs_suffix FILTER html %]">[x]</a>
</form>
</li>
<li id="forgot_container[% qs_suffix %]">
<span class="separator">| </span>
<a id="forgot_link[% qs_suffix %]" href="[% script_url FILTER html %]#forgot"
- onclick="return show_forgot_form('[% qs_suffix %]')">Forgot Password</a>
+ class='show_forgot_form'
+ data-qs-suffix="[% qs_suffix FILTER html %]">Forgot Password</a>
<form action="token.cgi" method="post" id="forgot_form[% qs_suffix %]"
class="mini_forgot bz_default_hidden">
<label for="login[% qs_suffix FILTER html %]">Login:</label>
@@ -92,6 +94,6 @@
type="submit">
<input type="hidden" name="a" value="reqpw">
<input type="hidden" id="token[% qs_suffix FILTER html %]" name="token" value="[% issue_hash_token(['reqpw']) FILTER html %]">
- <a href="#" onclick="return hide_forgot_form('[% qs_suffix %]')">[x]</a>
+ <a href="#" class="hide_forgot_form" data-qs-suffix="[% qs_suffix FILTER html %]">[x]</a>
</form>
</li>
diff --git a/template/en/default/bug/process/bugmail.html.tmpl b/template/en/default/bug/process/bugmail.html.tmpl
index 0c4f2f27d..0e392c760 100644
--- a/template/en/default/bug/process/bugmail.html.tmpl
+++ b/template/en/default/bug/process/bugmail.html.tmpl
@@ -35,20 +35,25 @@
%]
[% recipient_count = sent_bugmail.sent.size %]
-<script>
-function toggleBugmailRecipients(bug_id, show) {
- if (show) {
- YAHOO.util.Dom.removeClass('bugmail_summary_' + bug_id, 'bz_default_hidden');
- YAHOO.util.Dom.addClass('bugmail_summary_' + bug_id + '_short', 'bz_default_hidden');
- } else {
- YAHOO.util.Dom.addClass('bugmail_summary_' + bug_id, 'bz_default_hidden');
- YAHOO.util.Dom.removeClass('bugmail_summary_' + bug_id + '_short', 'bz_default_hidden');
+<script [% script_nonce FILTER none %]>
+ function toggleBugmailRecipients(bug_id, show) {
+ if (show) {
+ $("#bugmail_summary_" + bug_id).show();
+ $("#bugmail_summary_" + bug_id + "_short").hide();
+ } else {
+ $("#bugmail_summary_" + bug_id).hide();
+ $("#bugmail_summary_" + bug_id + "_short").show();
+ }
+ $.cookie('show_bugmail_recipients', (show ? 1 : 0), {
+ expires: new Date("January 12, 2025")
+ });
}
- YAHOO.util.Cookie.set('show_bugmail_recipients', (show ? 1 : 0), {
- expires: new Date("January 12, 2025")
- });
- return false;
-}
+ $(function() {
+ $(".toggleBugmailRecipients").on("click", function (event) {
+ event.preventDefault();
+ toggleBugmailRecipients($(this).data('mailing-bugid'), $(this).data('mailing-show'));
+ });
+ });
</script>
<dl id="bugmail_summary_[% mailing_bugid FILTER none %]"
@@ -63,7 +68,8 @@ function toggleBugmailRecipients(bug_id, show) {
[% ELSE %]
no one
[% END %]
- (<a href="#" onclick="return toggleBugmailRecipients([% mailing_bugid FILTER none %], false)">hide</a>)
+ (<a href="#" class="toggleBugmailRecipients" data-mailing-bugid="[% mailing_bugid FILTER html %]"
+ data-mailing-show="false">hide</a>)
[% ELSE %]
(list of e-mails not available)
[% END %]
@@ -74,7 +80,8 @@ function toggleBugmailRecipients(bug_id, show) {
class="[% show_recipients ? "bz_default_hidden" : "" %]">
[% IF recipient_count > 0 %]
Email sent to [% recipient_count FILTER html %] recipient[% 's' UNLESS recipient_count == 1 %].
- (<a href="#" onclick="return toggleBugmailRecipients([% mailing_bugid FILTER none %], true)">show</a>)
+ (<a href="#" class="toggleBugmailRecipients" data-mailing-bugid="[% mailing_bugid FILTER html %]"
+ data-mailing-show="true">show</a>)
[% ELSE %]
No emails were sent.
[% END %]
diff --git a/template/en/default/global/common-links.html.tmpl b/template/en/default/global/common-links.html.tmpl
index 50cfa020c..76b0855d8 100644
--- a/template/en/default/global/common-links.html.tmpl
+++ b/template/en/default/global/common-links.html.tmpl
@@ -31,9 +31,7 @@
<li class="form quicksearch_form">
<span class="separator">| </span>
<form action="buglist.cgi" method="get"
- onsubmit="if (this.quicksearch.value == '')
- { alert('Please enter one or more search terms first.');
- return false; } return true;">
+ class='quicksearch_check_empty'>
<input class="txt" type="text" id="quicksearch[% qs_suffix FILTER html %]" name="quicksearch"
title="Quick Search" value="[% quicksearch FILTER html %]">
<input class="btn" type="submit" value="Search"
diff --git a/template/en/default/global/header.html.tmpl b/template/en/default/global/header.html.tmpl
index 1ef96a553..2e08a461d 100644
--- a/template/en/default/global/header.html.tmpl
+++ b/template/en/default/global/header.html.tmpl
@@ -181,15 +181,17 @@
[% PROCESS format_js_link %]
[% END %]
- <script type="text/javascript">
+ <script [% script_nonce FILTER none %] type="text/javascript">
<!--
[% IF NOT no_yui %]
YAHOO.namespace('bugzilla');
+ [% IF 0 %]
YAHOO.util.Event.addListener = function (el, sType, fn, obj, overrideContext) {
if ( ("onpagehide" in window || YAHOO.env.ua.gecko) && sType === "unload") { sType = "pagehide"; };
var capture = ((sType == "focusin" || sType == "focusout") && !YAHOO.env.ua.ie) ? true : false;
return this._addListener(el, this._getType(sType), fn, obj, overrideContext, capture);
};
+ [% END %]
if ( "onpagehide" in window || YAHOO.env.ua.gecko) {
YAHOO.util.Event._simpleRemove(window, "unload",
YAHOO.util.Event._unload);
@@ -277,8 +279,12 @@
[%# Migration note: contents of the old Param 'bodyhtml' go in the body tag,
# but set the onload attribute in the DEFAULT directive above.
#%]
-
- <body onload="[% onload %]"
+ [% IF onload %]
+ <script [% script_nonce FILTER none %]>
+ $(function() { [% onload %] });
+ </script>
+ [% END %]
+ <body
class="[% urlbase.replace('^https?://','').replace('/$','').replace('[-~@:/.]+','-') FILTER css_class_quote %]
skin-[% user.settings.skin.value FILTER css_class_quote %]
[% FOREACH class = bodyclasses %]
@@ -445,5 +451,5 @@
[% END %]
[% BLOCK format_js_link %]
- <script type="text/javascript" src="[% asset_url FILTER mtime FILTER html %]"></script>
+ <script [% script_nonce FILTER none %] type="text/javascript" src="[% asset_url FILTER mtime FILTER html %]"></script>
[% END %]
diff --git a/template/en/default/global/per-bug-queries.html.tmpl b/template/en/default/global/per-bug-queries.html.tmpl
index 90418981f..71723c178 100644
--- a/template/en/default/global/per-bug-queries.html.tmpl
+++ b/template/en/default/global/per-bug-queries.html.tmpl
@@ -15,7 +15,7 @@
[% IF user.id && user.settings.per_bug_queries.value == "on" %]
<li id="links-special">
- <script type="text/javascript">
+ <script [% script_nonce FILTER none %] type="text/javascript">
<!--
function update_text() {
// 'lob' means list_of_bugs.
@@ -48,6 +48,10 @@
old_lists.disabled = false;
}
}
+ $(function() {
+ $("#lob_action").on("change", update_text);
+ $("#lob_newqueryname").on("keyup", manage_old_lists);
+ });
//-->
</script>
@@ -58,7 +62,7 @@
<input type="hidden" name="remtype" value="asnamed">
<input type="hidden" name="list_of_bugs" value="1">
<input type="hidden" name="token" value="[% issue_hash_token(['savedsearch']) FILTER html %]">
- <select id="lob_action" name="action" onchange="update_text();">
+ <select id="lob_action" name="action" >
<option value="add">Add</option>
[% IF user.tags.size %]
<option value="remove">Remove</option>
@@ -81,8 +85,7 @@
<span id="lob_new_query_text">
[% " or create and add the tag" IF user.tags.size %]
<input class="txt" type="text" id="lob_newqueryname"
- size="20" maxlength="64" name="newqueryname"
- onkeyup="manage_old_lists();">
+ size="20" maxlength="64" name="newqueryname">
</span>
<span id="lob_direction">to</span>
[%+ terms.bugs %]
diff --git a/template/en/default/global/userselect.html.tmpl b/template/en/default/global/userselect.html.tmpl
index f7dc03d89..5577448fb 100644
--- a/template/en/default/global/userselect.html.tmpl
+++ b/template/en/default/global/userselect.html.tmpl
@@ -11,7 +11,6 @@
# id: optional; field id
# value: optional; default field value/selection
# classes: optional; an array of classes to be added
- # onchange: optional; onchange attribute value
# disabled: optional; if true, the field is disabled
# accesskey: optional, input only; accesskey attribute value
# size: optional, input only; size attribute value
@@ -24,11 +23,12 @@
# mandatory: optional; if true, the field cannot be empty.
#%]
+[% THROW "onchange is not allowed" IF onchange %]
+
[% IF Param("usemenuforusers") %]
<select name="[% name FILTER html %]"
[% IF id %] id="[% id FILTER html %]" [% END %]
[% IF classes %] class="[% classes.join(' ') FILTER html %]" [% END %]
- [% IF onchange %] onchange="[% onchange FILTER html %]" [% END %]
[% IF disabled %] disabled="[% disabled FILTER html %]" [% END %]
[% IF accesskey %] accesskey="[% accesskey FILTER html %]" [% END %]
[% IF multiple %] multiple="multiple" size="[% multiple FILTER html %]" [% END %]
@@ -86,7 +86,6 @@
name="[% name FILTER html %]"
value="[% value FILTER html %]"
[% IF classes %] class="[% classes.join(' ') FILTER html %]" [% END %]
- [% IF onchange %] onchange="[% onchange FILTER html %]" [% END %]
[% IF disabled %] disabled="[% disabled FILTER html %]" [% END %]
[% IF accesskey %] accesskey="[% accesskey FILTER html %]" [% END %]
[% IF field_title %] title="[% field_title FILTER html %]" [% END %]
diff --git a/template/en/default/index.html.tmpl b/template/en/default/index.html.tmpl
index f99287d49..a3fa0a906 100644
--- a/template/en/default/index.html.tmpl
+++ b/template/en/default/index.html.tmpl
@@ -32,7 +32,7 @@
style_urls = [ 'skins/standard/index.css' ]
%]
-<script type="text/javascript">
+<script [% script_nonce FILTER none %] type="text/javascript">
function checkQuicksearch( form ) {
if (form.quicksearch.value == '') {
alert('Please enter one or more search terms first.');
@@ -40,6 +40,11 @@ function checkQuicksearch( form ) {
}
return true;
}
+$(function () {
+ $("#quicksearchForm").on("submit", function (event) {
+ return checkQuicksearch(this);
+ });
+});
</script>
<div id="page-index">
@@ -63,8 +68,7 @@ function checkQuicksearch( form ) {
href="?GoAheadAndLogIn=1"><span>Log In</span></a>
[% END %]
- <form id="quicksearchForm" name="quicksearchForm" action="buglist.cgi"
- onsubmit="return checkQuicksearch(this);">
+ <form id="quicksearchForm" name="quicksearchForm" action="buglist.cgi">
<div>
<input id="quicksearch_main" type="text" name="quicksearch"
placeholder="Enter [% terms.abug %] number or some search terms"
diff --git a/template/en/default/pages/quicksearch.html.tmpl b/template/en/default/pages/quicksearch.html.tmpl
index 18bf4dfb1..a3359752f 100644
--- a/template/en/default/pages/quicksearch.html.tmpl
+++ b/template/en/default/pages/quicksearch.html.tmpl
@@ -31,9 +31,7 @@
<p>Type in one or more words (or pieces of words) to search for:</p>
<form name="f" action="buglist.cgi" method="get"
- onsubmit="if (this.quicksearch.value == '')
- { alert('Please enter one or more search terms first.');
- return false; } return true;">
+ class='quicksearch_check_empty'>
<input type="text" size="40" name="quicksearch">
<input type="submit" value="Search" id="find">
</form>