From 742fab1ca9c0e66f46fbaf08af26c31b5e5fd9a3 Mon Sep 17 00:00:00 2001 From: Dylan Hardison Date: Thu, 28 Jul 2016 13:49:14 -0400 Subject: Bug 1286287 - Add utility method to Bugzilla::CGI for configuring CSP headers r=dkl,a=dylan --- Bugzilla/CGI.pm | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'Bugzilla/CGI.pm') diff --git a/Bugzilla/CGI.pm b/Bugzilla/CGI.pm index b341a86f1..88dfeb4d2 100644 --- a/Bugzilla/CGI.pm +++ b/Bugzilla/CGI.pm @@ -22,6 +22,12 @@ use Bugzilla::Install::Util qw(i_am_persistent); use File::Basename; +use constant DEFAULT_CSP => ( + default_src => [ 'self' ], + script_src => [ 'self', 'unsafe-inline', 'unsafe-eval' ], + style_src => [ 'self', 'unsafe-inline' ], +); + sub _init_bz_cgi_globals { my $invocant = shift; # We need to disable output buffering - see bug 179174 @@ -102,6 +108,39 @@ sub new { return $self; } +sub content_security_policy { + my ($self) = @_; + if (Bugzilla->has_feature('csp')) { + require Bugzilla::CGI::ContentSecurityPolicy; + return $self->{Bugzilla_csp} if $self->{Bugzilla_csp}; + my %params = DEFAULT_CSP; + if (@_) { + my %add_params = @_; + foreach my $key (keys %add_params) { + if (defined $add_params{$key}) { + $params{$key} = $add_params{$key}; + } + else { + delete $params{$key}; + } + } + } + return $self->{Bugzilla_csp} = Bugzilla::CGI::ContentSecurityPolicy->new(%params); + } + return undef; +} + +sub csp_nonce { + my ($self) = @_; + + if (Bugzilla->has_feature('csp')) { + my $csp = $self->content_security_policy; + return $csp->nonce if $csp->has_nonce; + } + + return ''; +} + # We want this sorted plus the ability to exclude certain params sub canonicalise_query { my ($self, @exclude) = @_; @@ -336,6 +375,9 @@ sub header { # the MIME type away from the declared Content-Type. $headers{'-x_content_type_options'} = 'nosniff'; + my $csp = $self->content_security_policy; + $csp->add_cgi_headers(\%headers) if defined $csp; + Bugzilla::Hook::process('cgi_headers', { cgi => $self, headers => \%headers } ); @@ -646,6 +688,18 @@ correctly, using C or the mod_perl APIs as appropriate. To remove (expire) a cookie, use C. +=item C + +Set a Content Security Policy for the current request. This is a no-op if the 'csp' feature +is not available. The arguments to this method are passed to the constructor of L, +consult that module for a list of what directives are supported. + +=item C + +Returns a CSP nonce value if CSP is available and 'nonce' is listed as a source in a CSP *_src directive. + +If there is no nonce used, or CSP is not available, this returns the empty string. + =item C This is a wrapper around send_cookie, setting an expiry date in the past, -- cgit v1.2.3-24-g4f1b