Nonce-Based Content Security Policy for Scripts
Adds a fresh random nonce to every script WordPress prints and sends a strict, nonce-based script policy (report-only by default), the modern way to block injected scripts.
Opens WPIDE on
Code
// Switch to true to enforce the policy once nothing legitimate is reported.
$wpide_nonce_enforce = false;
$wpide_csp_nonce = function () {
static $nonce = null;
if ( null === $nonce ) {
$nonce = rtrim( strtr( base64_encode( random_bytes( 18 ) ), '+/', '-_' ), '=' );
}
return $nonce;
};
$wpide_add_nonce = function ( $attributes ) use ( $wpide_csp_nonce ) {
if ( is_array( $attributes ) && ! isset( $attributes['nonce'] ) ) {
$attributes['nonce'] = $wpide_csp_nonce();
}
return $attributes;
};
add_filter( 'wp_script_attributes', $wpide_add_nonce );
add_filter( 'wp_inline_script_attributes', $wpide_add_nonce );
add_action( 'send_headers', function () use ( $wpide_csp_nonce, $wpide_nonce_enforce ) {
if ( headers_sent() ) {
return;
}
$policy = sprintf( "script-src 'nonce-%s' 'strict-dynamic' https: 'unsafe-inline'; object-src 'none'; base-uri 'self'", $wpide_csp_nonce() );
header( ( $wpide_nonce_enforce ? 'Content-Security-Policy: ' : 'Content-Security-Policy-Report-Only: ' ) . $policy );
} );
Notes
Scripts hard-coded into theme templates do not get the nonce and full-page caches reuse it, so check the console with your cache active before setting $wpide_nonce_enforce to true.
How to add this snippet
- Install WPIDE on your WordPress site (it is free) and open Code Snippets.
- Use snippet above adds it from the library in one click. Or copy the code into a new snippet with the same code type.
- It is added inactive: review the code and settings, then switch it on.