Skip to content

Commit 7c5730b

Browse files
authored
Merge pull request #36 from BeAPI/feat/update-default-http-headers
feat (default-http-headers): add missing pieces for report-to CSP directive and don't override original headers
2 parents ad4e4d2 + e5d57cb commit 7c5730b

File tree

1 file changed

+63
-29
lines changed

1 file changed

+63
-29
lines changed

default-http-headers.php

Lines changed: 63 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
22
/*
33
Plugin Name: BeAPI Default - HTTP Headers
4-
Version: 1.0.0
4+
Version: 1.1.0
55
Plugin URI: https://beapi.fr
66
Description: Add custom http headers (CP, CSP, ....)
77
Author: Be API
@@ -41,37 +41,70 @@
4141
* @return array
4242
*
4343
* @author Alexandre Sadowski
44-
*
4544
*/
4645
function wp_headers( array $headers ): array {
4746
if ( is_admin() ) {
4847
return $headers;
4948
}
5049

51-
$csp = get_csp_headers();
50+
$csp = get_csp_headers();
51+
$has_report_url = defined( 'WP_SENTRY_SECURITY_HEADER_ENDPOINT' ) && ! empty( WP_SENTRY_SECURITY_HEADER_ENDPOINT );
52+
$report_only = defined( 'CSP_REPORT_ONLY' ) && CSP_REPORT_ONLY;
53+
54+
if ( $report_only && $has_report_url ) {
55+
$report_url = WP_SENTRY_SECURITY_HEADER_ENDPOINT;
56+
// include env name in the URL if available.
57+
if ( defined( 'WP_SENTRY_ENV' ) && ! empty( WP_SENTRY_ENV ) ) {
58+
$report_url = add_query_arg( array( 'sentry_environment' => WP_SENTRY_ENV ), $report_url );
59+
}
5260

53-
if ( defined( 'CSP_REPORT_ONLY' ) && defined( 'WP_SENTRY_SECURITY_HEADER_ENDPOINT' ) ) {
54-
$csp['report-uri'] = WP_SENTRY_SECURITY_HEADER_ENDPOINT;
55-
$csp['report-to'] = 'csp-endpoint';
61+
/**
62+
* Setup CSP violation reporting.
63+
*
64+
* @see https://docs.sentry.io/platforms/go/security-policy-reporting/#content-security-policy Sentry documentation on setting the CSP reporting.
65+
*/
66+
// CSP directives use for reporting CSP violations.
67+
$csp['report-to'] = 'csp-endpoint';
68+
69+
// Deprecated CSP directive for reporting, kept for compatibility with old browsers.
70+
$csp['report-uri'] = $report_url;
71+
72+
// Include reporting endpoint domain to the list of allowed host
73+
$csp['connect-src'] = ( $csp['connect-src'] ?? '' ) . ' ' . wp_parse_url( $report_url, PHP_URL_HOST );
74+
75+
// Additional headers required by the "report-to" CSP directive.
76+
$headers['Report-To'] = wp_json_encode(
77+
[
78+
'group' => 'csp-endpoint',
79+
'max_age' => 10886400,
80+
'endpoints' => [
81+
'url' => $report_url,
82+
'include_subdomains' => true,
83+
]
84+
]
85+
);
86+
$headers['Reporting-Endpoints'] = sprintf( 'csp-endpoint="%s"', $report_url );
5687
}
5788

5889
/**
5990
* We rely on the CSP_REPORT_ONLY .env value to decide whether we apply the CSP or just report the errors
6091
*/
61-
$csp_header = defined( 'CSP_REPORT_ONLY' ) && CSP_REPORT_ONLY ? 'Content-Security-Policy-Report-Only' : 'Content-Security-Policy';
62-
$csp_headers_array[ $csp_header ] = get_prepare_csp( $csp );
92+
$csp_header = $report_only ? 'Content-Security-Policy-Report-Only' : 'Content-Security-Policy';
93+
$headers[ $csp_header ] = get_prepare_csp( $csp );
6394

64-
$custom_headers_array = [];
65-
66-
/**$custom_headers_array = [
67-
* 'X-Content-Type-Options' => 'nosniff',
68-
* 'X-Frame-Options' => 'SAMEORIGIN',
69-
* 'X-XSS-Protection' => '1; mode=block',
70-
* 'Referrer-Policy' => 'no-referrer-when-downgrade',
71-
* 'Permissions-Policy' => 'accelerometer=(), geolocation=(), fullscreen=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), display-capture=()',
72-
* ];**/
95+
/**
96+
* Additional security headers.
97+
*
98+
* Example :
99+
* $headers['X-Content-Type-Options'] = 'nosniff';
100+
* $headers['X-Frame-Options'] = 'SAMEORIGIN';
101+
* $headers['Referrer-Policy'] = 'no-referrer-when-downgrade';
102+
* $headers['Permissions-Policy'] = 'accelerometer=(), geolocation=(), fullscreen=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), display-capture=()';
103+
*/
104+
$headers['X-Content-Type-Options'] = 'nosniff';
105+
$headers['X-Frame-Options'] = 'SAMEORIGIN';
73106

74-
return wp_parse_args( $csp_headers_array, $custom_headers_array );
107+
return $headers;
75108
}
76109

77110
add_filter( 'wp_headers', __NAMESPACE__ . '\\wp_headers', 99 );
@@ -111,20 +144,21 @@ function get_prepare_csp( array $csp ): string {
111144
*/
112145
function get_csp_headers(): array {
113146
$csp = [
114-
'default-src' => '\'self\'',
115-
'script-src' => '\'self\'',
116-
'style-src' => '\'self\'',
117-
'img-src' => '\'self\'',
118-
'font-src' => '\'self\'',
119-
'connect-src' => '\'self\'',
120-
'frame-src' => '\'self\'',
121-
'manifest-src' => '\'self\'',
122-
'worker-src' => '\'self\'',
123-
'object-src' => '\'none\'',
147+
'default-src' => "'self'",
148+
'script-src' => "'self'",
149+
'style-src' => "'self'",
150+
'img-src' => "'self'",
151+
'font-src' => "'self'",
152+
'connect-src' => "'self'",
153+
'frame-src' => "'self'",
154+
'manifest-src' => "'self'",
155+
'worker-src' => "'self'",
156+
'object-src' => "'self'",
157+
'base-uri' => "'self'",
124158
];
125159

126160
//if ( 'production' === WP_ENV ) {
127-
//$csp = [];
161+
// $csp = [];
128162
//}
129163

130164
return apply_filters( 'csp_headers', $csp );

0 commit comments

Comments
 (0)