简体   繁体   中英

How to allow Inline JS Scripts using Nonces for CSP

I am trying to implement CSP on my site. I change my inline scripts a lot, so hashes are a bad idea for me for CSP

I read that Nonces which are random integers can be used to implement CSP.

I am using WordPress. And below is my CSP header.

Header add Content-Security-Policy "default-src 'self'; script-src unsafe-hashes 'self' https://milyin.com https://cdnjs.cloudflare.com https://cdn.tiny.cloud  https:; object-src 'none';base-uri 'none';img-src https: data:;style-src 'self' 'unsafe-inline' https://fonts.googleapis.com https://www.google.com https:;report-uri https://milyin.com/?csp=true"

As you might be able to tell, inline scripts wont execute from it. So how to implement it.

Initial research found me the idea of hashes, and the fact that I can get hash of scripts from chrome Dev Tools made it simple and obvious.

However, the fact that slightest change to any script would require me to change the hash was a headache.

So I heard of nonces.

Please suggest how to implement it, and (if possible) tell if their exists some easier way for wordpress user like me.

So I have couple of doubts:

  1. What is Nonce? As far as I understand it's a random integer of my liking.

  2. Can I use same nonce all scripts? I mean can i put say Header add Content-Security-Policy "default-src 'self'; script-src 'self' 'nonce-69' and then put <script nonce="69" in each and every script of my site?

  3. Do I need to change Nonce frequently? I mean if Nonce is constant then someone can simply put inject script with same nonce and get it working. How to prevent that.

1.) What is Nonce? As far as I understand it's a random integer of my liking.

Nonce is base64 encoded value:

; Nonces: 'nonce-[nonce goes here]'
nonce-source  = "'nonce-" base64-value "'"
base64-value  = 1*( ALPHA / DIGIT / "+" / "/" / "-" / "_" )*2( "=" )

2.) Can I use same nonce all scripts? I mean can i put say Header add Content-Security-Policy "default-src 'self'; script-src 'self' 'nonce-69' and then put <script nonce="69" in each and every script of my site?

Yes, you can use once generated nonce and do not need to generate a new nonce for each script on the page.
To generate nonce you can use:

3.) Do I need to change Nonce frequently? I mean if Nonce is constant then someone can simply put inject script with same nonce and get it working. How to prevent that.

According to CSP spec The server MUST generate a unique nonce value each time it transmits a policy. The generated value SHOULD be at least 128 bits long (before encoding), and SHOULD be generated via a cryptographically secure random number generator in order to ensure that the value is difficult for an attacker to predict.
It means you must regenerate a nonce on each page loading.

BTW, you have an error in the ... script-src unsafe-hashes 'self' ... - the unsafe-hashes token should be a single-quoted: 'unsafe-hashes' . But anyway it's not useful since it's not supported by Safari.

A unique nonce has to be generated for every pages load The architecture to roll-out a nonce-based CSP is generally used in custom web applications - and would be very complex for a Wordpress site, as I imagine that you may be using Caching / CDN.

I would suggest remaining with the 'unsafe-inline' for the Wordpress site. If you have other more important pages (like a checkout page / admin page), you can create a separate CSP.

With that said, if you do go ahead and implement a CSP with nonces, you will probably need to add the 'strict-dynamic' and 'unsafe-eval' permissions.

I wrote a small class to generated the header and nonce to be used later. Every construct of the CspBuilder class will create a unique nonce which can be used later. As long as the scripts are referenced in a .php file this will work:

$Csp = (new \CspBuilder(true))
    -> addCspPolicyNonce(CspDirective::Script)
    -> setCspHeader();

The side effect of setCspHeader() is the generation of a complete Content-Security-Policy . Wherever including a script in a PHP file use:

<script nonce="<?=$Csp->getNonce?>">

There are many more options in this small, fully type-checked class. Read the description or the code. Link here: https://github.com/theking2/php-csp-builder

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM