Bug 38365: Move default Content-Security-Policy value into Perl module
By defining a default policy in the Perl module, we can easily update it over time. Using koha-conf.xml will just be for overrides, so people can manage their own there. Signed-off-by: Lari Taskula <lari.taskula@hypernova.fi> Signed-off-by: David Cook <dcook@prosentient.com.au> Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org> Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
This commit is contained in:
parent
b14528e2f8
commit
da52fd9c6f
|
|
@ -88,11 +88,10 @@ sub header_name {
|
|||
|
||||
my $conf_csp = $self->{config}->get('content_security_policy');
|
||||
|
||||
Koha::Exceptions::Config::MissingEntry->throw( error => 'Missing request content_security_policy csp_header_value' )
|
||||
unless exists $conf_csp->{$interface}->{csp_mode};
|
||||
|
||||
return 'Content-Security-Policy-Report-Only' if $conf_csp->{$interface}->{csp_mode} eq 'report-only';
|
||||
return 'Content-Security-Policy' if $conf_csp->{$interface}->{csp_mode} eq 'enabled';
|
||||
if ( $conf_csp && $conf_csp->{$interface} && $conf_csp->{$interface}->{csp_mode} ) {
|
||||
return 'Content-Security-Policy-Report-Only' if $conf_csp->{$interface}->{csp_mode} eq 'report-only';
|
||||
return 'Content-Security-Policy' if $conf_csp->{$interface}->{csp_mode} eq 'enabled';
|
||||
}
|
||||
|
||||
Koha::Exceptions::Config::MissingEntry->throw(
|
||||
error => 'Content Security Policy is disabled. Header name should only be retrieved when CSP is enabled.' );
|
||||
|
|
@ -112,8 +111,6 @@ sub header_name {
|
|||
|
||||
Returns content_security_policy.[opac|staff].csp_header_value
|
||||
|
||||
Throws Koha::Exceptions::Config::MissingEntry is CSP property "csp_header_value" is missing in KOHA_CONF
|
||||
|
||||
=cut
|
||||
|
||||
sub header_value {
|
||||
|
|
@ -121,15 +118,29 @@ sub header_value {
|
|||
|
||||
my $interface = $args->{interface} || C4::Context->interface;
|
||||
|
||||
my @default_policy_lines = (
|
||||
q#default-src 'self'#,
|
||||
q# script-src 'self' 'nonce-_CSP_NONCE_'#,
|
||||
q# style-src 'self' 'nonce-_CSP_NONCE_'#,
|
||||
q# style-src-attr 'unsafe-inline'#,
|
||||
q# img-src 'self' data:#,
|
||||
q# font-src 'self'#,
|
||||
q# object-src 'none'#,
|
||||
);
|
||||
my $default_policy = join( ';', @default_policy_lines );
|
||||
|
||||
my $conf_csp = $self->{config}->get('content_security_policy');
|
||||
|
||||
Koha::Exceptions::Config::MissingEntry->throw( error => 'Missing request content_security_policy csp_header_value' )
|
||||
unless exists $conf_csp->{$interface}->{csp_header_value};
|
||||
my $user_policy = $conf_csp->{$interface}->{csp_header_value};
|
||||
|
||||
my $csp_header_value = $conf_csp->{$interface}->{csp_header_value};
|
||||
my $csp_policy = ($user_policy) ? $user_policy : $default_policy;
|
||||
|
||||
my $csp_header_value = $csp_policy;
|
||||
my $csp_nonce = $self->get_nonce;
|
||||
|
||||
$csp_header_value =~ s/_CSP_NONCE_/$csp_nonce/g;
|
||||
if ($csp_nonce) {
|
||||
$csp_header_value =~ s/_CSP_NONCE_/$csp_nonce/g;
|
||||
}
|
||||
|
||||
return $csp_header_value;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -514,21 +514,39 @@ __END_SRU_PUBLICSERVER__
|
|||
csp_header_value: The CSP policy directives. Special placeholders:
|
||||
- _CSP_NONCE_: Replaced with a unique nonce for each request
|
||||
|
||||
Recommended workflow:
|
||||
1. Start with report-only mode to identify violations
|
||||
2. Review logs and fix any legitimate violations
|
||||
3. Switch to enabled mode once violations are resolved
|
||||
NOTE: Koha comes with a hard-coded csp_header_value. You only need to define your own
|
||||
csp_header_value if you want or need a different Content-Security-Policy value.
|
||||
|
||||
To enable violation reporting, create your own csp_header_value including
|
||||
'report-to' pointing to csp-violations and add 'report-uri'.
|
||||
|
||||
NOTE: You must be using HTTPS to receive violation reports.
|
||||
|
||||
To enable violation reporting, add report-to to your policy pointing to csp-violations.
|
||||
Example with reporting:
|
||||
<csp_header_value>default-src 'self'; script-src 'self' 'nonce-_CSP_NONCE_'; style-src 'self' 'nonce-_CSP_NONCE_'; style-src-attr 'unsafe-inline'; img-src 'self' data:; font-src 'self'; object-src 'none'; report-uri /api/v1/public/csp-reports; report-to csp-violations</csp_header_value>
|
||||
<content_security_policy>
|
||||
<opac>
|
||||
<csp_mode>report-only</csp_mode>
|
||||
<csp_header_value>default-src 'self'; script-src 'self' 'nonce-_CSP_NONCE_'; style-src 'self' 'nonce-_CSP_NONCE_'; style-src-attr 'unsafe-inline'; img-src 'self' data:; font-src 'self'; object-src 'none'; report-uri /api/v1/public/csp-reports; report-to csp-violations</csp_header_value>
|
||||
</opac>
|
||||
<intranet>
|
||||
<csp_mode>report-only</csp_mode>
|
||||
<csp_header_value>default-src 'self'; script-src 'self' 'nonce-_CSP_NONCE_'; style-src 'self' 'nonce-_CSP_NONCE_'; style-src-attr 'unsafe-inline'; img-src 'self' data:; font-src 'self'; object-src 'none'; report-uri /api/v1/public/csp-reports; report-to csp-violations</csp_header_value>
|
||||
</intranet>
|
||||
</content_security_policy>
|
||||
|
||||
Reports are logged via Koha's logging system. Configure log4perl to capture them:
|
||||
log4perl.logger.api.csp = WARN, CSP
|
||||
log4perl.appender.CSP = Log::Log4perl::Appender::File
|
||||
log4perl.appender.CSP.filename = /var/log/koha/__KOHASITE__/csp-violations.log
|
||||
log4perl.appender.CSP.layout = PatternLayout
|
||||
log4perl.appender.CSP.layout.ConversionPattern = [%d] %m%n
|
||||
log4perl.logger.plack-csp = WARN, PLACKCSP
|
||||
log4perl.appender.PLACKCSP=Log::Log4perl::Appender::File
|
||||
log4perl.appender.PLACKCSP.filename=/var/log/koha/<kohasite>/plack-csp-violations.log
|
||||
log4perl.appender.PLACKCSP.mode=append
|
||||
log4perl.appender.PLACKCSP.layout=PatternLayout
|
||||
log4perl.appender.PLACKCSP.layout.ConversionPattern=[%d] %m%n
|
||||
log4perl.appender.PLACKCSP.utf8=1
|
||||
|
||||
Recommended workflow:
|
||||
1. Start with report-only mode to identify violations
|
||||
2. Review logs and fix any legitimate violations (by fixing the code or by modifying your csp_header_value)
|
||||
3. Switch to enabled mode once violations are resolved
|
||||
-->
|
||||
<content_security_policy>
|
||||
<opac>
|
||||
|
|
|
|||
|
|
@ -325,21 +325,39 @@
|
|||
csp_header_value: The CSP policy directives. Special placeholders:
|
||||
- _CSP_NONCE_: Replaced with a unique nonce for each request
|
||||
|
||||
Recommended workflow:
|
||||
1. Start with report-only mode to identify violations
|
||||
2. Review logs and fix any legitimate violations
|
||||
3. Switch to enabled mode once violations are resolved
|
||||
NOTE: Koha comes with a hard-coded csp_header_value. You only need to define your own
|
||||
csp_header_value if you want or need a different Content-Security-Policy value.
|
||||
|
||||
To enable violation reporting, create your own csp_header_value including
|
||||
'report-to' pointing to csp-violations and add 'report-uri'.
|
||||
|
||||
NOTE: You must be using HTTPS to receive violation reports.
|
||||
|
||||
To enable violation reporting, add report-to to your policy pointing csp-violations.
|
||||
Example with reporting:
|
||||
<csp_header_value>default-src 'self'; script-src 'self' 'nonce-_CSP_NONCE_'; style-src 'self' 'nonce-_CSP_NONCE_'; style-src-attr 'unsafe-inline'; img-src 'self' data:; font-src 'self'; object-src 'none'; report-uri /api/v1/public/csp-reports; report-to csp-violations</csp_header_value>
|
||||
<content_security_policy>
|
||||
<opac>
|
||||
<csp_mode>report-only</csp_mode>
|
||||
<csp_header_value>default-src 'self'; script-src 'self' 'nonce-_CSP_NONCE_'; style-src 'self' 'nonce-_CSP_NONCE_'; style-src-attr 'unsafe-inline'; img-src 'self' data:; font-src 'self'; object-src 'none'; report-uri /api/v1/public/csp-reports; report-to csp-violations</csp_header_value>
|
||||
</opac>
|
||||
<intranet>
|
||||
<csp_mode>report-only</csp_mode>
|
||||
<csp_header_value>default-src 'self'; script-src 'self' 'nonce-_CSP_NONCE_'; style-src 'self' 'nonce-_CSP_NONCE_'; style-src-attr 'unsafe-inline'; img-src 'self' data:; font-src 'self'; object-src 'none'; report-uri /api/v1/public/csp-reports; report-to csp-violations</csp_header_value>
|
||||
</intranet>
|
||||
</content_security_policy>
|
||||
|
||||
Reports are logged via Koha's logging system. Configure log4perl to capture them:
|
||||
log4perl.logger.api.csp = WARN, CSP
|
||||
log4perl.appender.CSP = Log::Log4perl::Appender::File
|
||||
log4perl.appender.CSP.filename = /var/log/koha/csp-violations.log
|
||||
log4perl.appender.CSP.layout = PatternLayout
|
||||
log4perl.appender.CSP.layout.ConversionPattern = [%d] %m%n
|
||||
log4perl.logger.plack-csp = WARN, PLACKCSP
|
||||
log4perl.appender.PLACKCSP=Log::Log4perl::Appender::File
|
||||
log4perl.appender.PLACKCSP.filename=/var/log/koha/<kohasite>/plack-csp-violations.log
|
||||
log4perl.appender.PLACKCSP.mode=append
|
||||
log4perl.appender.PLACKCSP.layout=PatternLayout
|
||||
log4perl.appender.PLACKCSP.layout.ConversionPattern=[%d] %m%n
|
||||
log4perl.appender.PLACKCSP.utf8=1
|
||||
|
||||
Recommended workflow:
|
||||
1. Start with report-only mode to identify violations
|
||||
2. Review logs and fix any legitimate violations (by fixing the code or by modifying your csp_header_value)
|
||||
3. Switch to enabled mode once violations are resolved
|
||||
-->
|
||||
<content_security_policy>
|
||||
<opac>
|
||||
|
|
|
|||
|
|
@ -117,22 +117,13 @@ subtest 'header_name tests' => sub {
|
|||
};
|
||||
|
||||
subtest 'header_value tests' => sub {
|
||||
plan tests => 6;
|
||||
plan tests => 3;
|
||||
|
||||
t::lib::Mocks::mock_config( $conf_csp_section, {} );
|
||||
C4::Context->interface('opac');
|
||||
|
||||
my $csp = Koha::ContentSecurityPolicy->new;
|
||||
|
||||
throws_ok { $csp->header_value } 'Koha::Exceptions::Config::MissingEntry',
|
||||
'Exception thrown when missing csp_header_value';
|
||||
|
||||
t::lib::Mocks::mock_config( $conf_csp_section, { opac => {} } );
|
||||
throws_ok { $csp->header_value } 'Koha::Exceptions::Config::MissingEntry',
|
||||
'Exception thrown when missing csp_header_value';
|
||||
|
||||
t::lib::Mocks::mock_config( $conf_csp_section, { opac => { csp_header_value => '' } } );
|
||||
is( $csp->header_value, '', 'Even an empty csp_header_value is retrieved form koha-conf.xml' );
|
||||
t::lib::Mocks::mock_config( $conf_csp_section, { opac => { csp_header_value => 'some value' } } );
|
||||
is( $csp->header_value, 'some value', 'csp_header_value is retrieved from koha-conf.xml' );
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue