8
votes

We're working on creating a strict Content Security Policy (https://csp.withgoogle.com/docs/strict-csp.html) which necessitates Apache creating a nonce each time a resource is requested, so that we can insert this nonce into the http header.

How can we create a nonce with Apache 2.4?

All of the CSP related documentation I've read says something to the effect of "A nonce is just a random string that's generated on the server, included in the CSP header..." but haven't found any info on how to do this with Apache. We could of course do this with app code, but doing it via Apache seems like a cleaner solution/will ensure every single page gets the CSP header.

4

4 Answers

4
votes

I would have preferred to simply add this as a comment but my reputation <50 does not allow it so I'm posting this as an answer instead.

In response to:

1.) apache generates a random string via mod_unique_id

This is a "unique" value not a "random" value, so you might want to be careful with its use as a CSP nonce.

2.) we insert this into our CSP header (not sure how to do this actually)

<IfModule mod_headers.c>
    <FilesMatch "\.(htm|html|php)$">
        Content-Security-Policy: script-src 'strict-dynamic' 'nonce-%{UNIQUE_ID}e' 'unsafe-inline' ' https:;
    </FilesMatch>
</IfModule>

I hope this helps.

4
votes

You need to generate the nonce on the server, and then have Apache pass that nonce to your script where it can be used.

We've created an open source module for Apache that simplifies this process: mod_cspnonce.

Here's a simple example of the server-side config:

LoadModule headers_module modules/mod_headers.so
LoadModule cspnonce_module modules/mod_cspnonce.so

# add the CSP_NONCE to the "default-src"
Header add Content-Security-Policy "default-src 'self' 'nonce-%{CSP_NONCE}e';"

Here's a simple example of using the nonce in your script:

<script nonce="<?= $_SERVER['CSP_NONCE'] ?>">
  var inline = 1;
</script>

That example is php, but you can use any language.

3
votes

After finding mod_unique_id, this was very easy (http://httpd.apache.org/docs/current/mod/mod_unique_id.html).

1.) Enable mod_unique_id. This is generally one line in httpd.conf: LoadModule unique_id_module modules/mod_unique_id.so

2.) mod_unique_id generates a unique string (see user3526609's answer, this may or may not be random enough for you) and server variable UNIQUE_ID set equal to that random string, on each page request, which you can then inject into your CSP and any inline code you need to whitelist. If you happen to use Php, $_SERVER['UNIQUE_ID'];

0
votes

The nonce has to be inserted into any element with inline CSS and/or Javascript handlers, so it has to be inserted at the application layer.

Parsing your output HTML and inserting nonces would defeat the whole purpose of CSP nonces -- the web server has no way of knowing if inline CSS/JS was supposed to be present, or if it was inserted by an attacker.