How to Add a Nonce to Inline WP Scripts, Such as For a Content-Security-Policy (Works with Gravity Forms)

A client of mine requires a fairly strict CSP, ie Content-Security-Policy, which dictates which domains’ scripts and styles can load from in an effort to combat XSS. I’ll leave the good folks at Mozilla to better define what a CSP is, but if you’ve been struggling to add a nonce to inline scripts, such as those added by Gravity Forms for its Recaptcha add-on, here is exactly how to do that.

All of this can go into functions.php or your custom plugin.

First, Create Your Nonce and Save it as a Session Variable

function cn_store_nonce_in_session() {
$_SESSION['cnnonce'] = wp_create_nonce('my_script_nonce_action');
}
function cn_retrieve_nonce_from_session() {
return $_SESSION['cnnonce'];
}
cn_store_nonce_in_session();

Next, We’ll Add the Nonce to All Inline Scripts

They all use the same one, so we should be able to safely do this across the board.

function cn_add_nonce_to_scripts( $attr ) {
$attr['nonce'] = cn_retrieve_nonce_from_session();
return $attr;
}
add_filter( 'wp_inline_script_attributes', 'cn_add_nonce_to_scripts' );

Finally, Add Our CSP

Note that my use of www.somewebsite.com clicknathan.com is just an example. There, you’d set any external domains, such as you may need for Google Tag Manager, Facebook Pixel, etc. You just separate them by spaces, and sudomains are important.

Also note the inline-speculation-rules declaration, which WordPress added in version 6.8. Read more about speculation rules here.

add_filter( 'wp_headers', function( array $headers ) {
$headers['Content-Security-Policy'] = "default-src 'self' www.somewebsite.com clicknathan.com; script-src 'self' 'nonce-".cn_retrieve_nonce_from_session()."' www.somewebsite.com clicknathan.com inline-speculation-rules; ";
return $headers;
});

How do I know this works and you’re not just a handsome devil, lying to me like Hollywood lies about the average human’s lack of six pack abs?

If you put everything together correctly, you can view the source of your site. Your inline scripts should now have a nonce like so:

<script id="some_script_generated_by_a_plugin_or_theme-js-extra" nonce="1223somethinghereXYZ">
var whatever_code = 'here';
</script>

Not working?

Feel free to reach out in the comments, or you can hire me to help with any of your WordPress needs!

Up Next: Woocommerce Remove Inline Styles Added After 9.9 Update