-
-
Save beastycoding/e316c1dd349bbd4ac9e9b0d15cdd24bd to your computer and use it in GitHub Desktop.
Add CSP to WordPress, including nonces for inline scripts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Plugin Name: Content Security Policy | |
* Version: 1.0.0 | |
* Description: Adds a Content-Security-Policy header to all non-admin requests. | |
* License: GNU General Public License v2 | |
* License URI: http://www.gnu.org/licenses/gpl-2.0.html | |
* Original Inspiration: https://gist.github.com/westonruter/c8b49406391a8d86a5864fb41a523ae9 | |
*/ | |
namespace App; | |
use function Roots\add_filters; | |
/** | |
* Gets CSP nonce. | |
*/ | |
function get_nonce(): string | |
{ | |
static $nonce = null; | |
if ($nonce === null) { | |
$nonce = wp_create_nonce('csp'); | |
} | |
return $nonce; | |
} | |
/** | |
* Gets Strict CSP header value. | |
*/ | |
function get_csp_header_value(): string | |
{ | |
return join( | |
'; ', | |
// Set your CSP below | |
[ | |
"font-src 'self' data:", | |
"frame-src 'none'", | |
"img-src 'self' data: secure.gravatar.com", | |
"manifest-src 'self'", | |
sprintf("script-src-elem 'nonce-%s' 'self'", get_nonce()), | |
"style-src-elem 'self' 'unsafe-inline'", // Unfortunately, inline CSS is not currently filterable | |
"object-src 'none'", | |
"base-uri 'none'" // Note: jQuery can violate this in jQuery.parseHTML() due to <https://github.com/jquery/jquery/issues/2965>. | |
"report-uri https://{{ your reporting uri }}", | |
] | |
); | |
} | |
/** | |
* Adds nonce attribute to script attributes. | |
*/ | |
add_filters( | |
['wp_script_attributes', 'wp_inline_script_attributes',], | |
function (array $attributes): array { | |
$attributes['nonce'] = get_nonce(); | |
return $attributes; | |
} | |
); | |
/** | |
* Sends Strict CSP header. | |
*/ | |
add_action('login_init', function () { | |
header(sprintf('Content-Security-Policy: %s', get_csp_header_value())); | |
}); | |
/** | |
* Send the header on the frontend and in the login screen. | |
*/ | |
add_filter( | |
'wp_headers', | |
static function ($headers) { | |
$headers['Content-Security-Policy'] = get_csp_header_value(); | |
return $headers; | |
} | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment