I am trying to implement CSP on my wordpress site.

Inspired by this question, https://stackoverflow.com/questions/50002041/adding-nonce-to-script-tag I tried to build a way to add nonces to my wordpress site.

add_action( 'run_custom_nonce_value', 'custom_nonce_value' );
function custom_nonce_value () {
    $created_nonce = wp_create_nonce();
    define( 'NONCE_RANDVALUE', $created_nonce ); 

This function was directly taken from the Stackoverflow link mentioned above.

It created Nonce Values using wp_create_nonce()

The major problem is that it creates a nonce but doesn't update it. Refreshing my wordpress site still shows the same nonce.

could global $variable be better option instead of define?

Anyways, after that the below code is slightly modified and adds the nonce to headers using WP actions and adds nonce to all scripts that are registered.

add_filter( 'script_loader_tag', 'add_nonce_to_script', 10, 3 );
function add_nonce_to_script( $tag, $handle, $source ) {
    $val_nonce = NONCE_RANDVALUE;
    $search = "type='text/javascript'";
    $replace = "type='text/javascript' nonce='".$val_nonce."' ";
    $subject = $tag;

    $output = str_replace($search, $replace, $subject);
    return $output;

function pagely_security_headers($headers) {
    $val_nonce = NONCE_RANDVALUE;
    $headers['X-Content-Security-Policy'] = "default-src 'self'; script-src unsafe-hashes 'self' https://milyin.com 'nonce-" . $val_nonce . "' https:; object-src 'none';base-uri 'none';img-src https: data:;style-src 'self' 'unsafe-inline' https:;report-uri https://milyin.com/?csp=true";
    return $headers;

add_filter( 'wp_headers', 'pagely_security_headers' );

So, we need to solve 2 things.

1.) It does not update the value of nonce, refreshing page and opening new tab still use the same value of nonce, diluting the entire purpose of nonces.

2.) A better way to echo the nonce elsewhere as I want inline scripts not registered in Wordpress to also have the nonce.

Also, I read CSP requires base64 nonces, are these nonces base64?

  • What you’re asking for is not an intended use case for WordPress nonces. WordPress nonces last up to 24 hours. If you want “true” nonces you would need to implement that yourself. Sep 10 at 4:51
  • And How to do that for a wordpress site? Sep 10 at 5:28
  • You can try passing a random value every time, something like wp_create_nonce(wp_hash_password(md5(rand(1000, 50000))));, this will create a random nonce every time. Sep 12 at 9:13
  • @Buttered_Toast as stated here stackoverflow.com/questions/69116549/… it needs to be a base64 value... To be honest I don't even understand what base64 means, but random ints between 1000 to 5000 probably aren't base64 because as far as I know from the examples it looks far more uglier than Integers like these Sep 12 at 9:18
  • 1
    Ok so you can wrap the wp_create_nonce in PHPs, base64_encode, so something like this base64_encode(wp_create_nonce(wp_hash_password(md5(rand(1000, 50000)))));. At this point I would not even use wp_create_nonce as you only need a base64, but do tests with both. Sep 12 at 10:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.