Update 2018-07-22: Well, I finally figured out why this is a bad idea! Nginx will generate the nonce even when it’s returning a 304 response. Firefox updates the cache with the new header and then refuses to execute the previously cached content. Chrome, incorrectly, does not do this.
I have been putting off fixing my Content-Security-Policy headers for a while now. Until today. It was a beautiful day out, so what better way to spend it fixing computer things that probably nobody even notices.
I figured this would have been a solved problem, so I punched it into a search
engine. The only relevant result seemed to be this blog post by Scott Helme. In it, he uses
set_secure_random_alphanum to generate
a nonce, and then substitutes a magic variable in his HTML pages. A perfectly
lazy an efficient worker, so I saw two problems with this:
- Recompiling nginx. Sure, it’s not hard, but who wants to repackage the thing every time Debian releases an update?
- Pages on this site are generated by Jekyll. Now there’s probably a way to modify the theme to include a magic variable, but ugh… effort.
So instead I opted to use nginx’s LUA support. Install the necessary packages:
I’m sure you can also do this through manual compilation or LuaRocks or whatever, but like I said, I’m lazy and apt is the best way to install stuff anyway.
With the necessary packages installed, add the following bit to your nginx configuration:
This will set the variable $cspNonce by reading from /dev/urandom. It reads 32 bytes (256 bits). Double the minimum recommended value of 16 bytes (128 bits). But feel free to fiddle with it.
The obvious next step is to add the nonce to all your
This will replace all instances of
<script to contain your nonce. Is this a good idea? Probably not, but since I’m not sure what will blow up exactly, let’s do it anyway.
Now all you need to do is add your
Content-Security-Policy header like suchly:
Restart nginx and you should be good to go. One thing to note is that this
will break any use of
gzip_static. You’re going to want to turn that off.
Cris van Pelt