12

Is anyone here able to clarify how caching affects adding a nonce=value to all inline javascript?

If the nonce must be unique and unpredictable, then one would need to disable all server-side (i.e. Varnish, Cloudfront, etc) caching on the pages that use <script nonce="XXXXX">. Correct?

See example 4 here for details.

Anders
  • 64,406
  • 24
  • 178
  • 215
user2687991
  • 141
  • 1
  • 6

3 Answers3

3

If the nonce must be unique and unpredictable, then one would need to disable all server-side (i.e. Varnish, Cloudfront, etc) caching on the pages that use <script nonce="XXXXX">. Correct?

Yes. You always have to disable caching on anything that is dynamically generated (i.e. comes from a script). Since you can't serve unique and unpredictable random values statically, it must be done from a script.

DepressedDaniel
  • 1,240
  • 6
  • 8
  • Thanks. That's the conclusion I came to as well, which makes this method impractical IMHO for all but the smallest sites. – user2687991 Dec 04 '16 at 07:51
  • @user2687991 Site size has little to do with it. If you have the money, you can always add more servers to handle the load. – DepressedDaniel Dec 04 '16 at 19:53
  • 2
    Couldn't you use or create a Varnish module that replaces a placeholder string with a nonce in every response? – glen-84 Apr 24 '17 at 20:59
  • @darkangel what keeps the attacker from including the placeholder? I don't think this is trivial to solve. – Prinzhorn Jul 12 '17 at 16:55
  • @Prinzhorn How would the attacker know what the placeholder string is? It could be absolutely anything, and could be updated frequently. – glen-84 Aug 27 '17 at 13:03
2

This can be happily cached by the application server for days without negatively impacting the CSP nonce protection.

No. The nonce should be unique for every request (nonce = number used once).

I guess the only solution is to use non-cached SSI (server side includes) for the script-tags containing the nonce and combinating that with the nonce in the response content security header or another little SSI for the meta http-equiv="Content-Security-Policy"-tag.

This will make every page unique and thus not cacheable.

10us
  • 121
  • 4
  • Please add this as a comment to https://security.stackexchange.com/a/162523/173376 and not a response to the question. I was really confused at first. – Keven Mar 12 '20 at 18:56
  • This is indeed just a comment and, with all respect, not even considering the strategy described there, which is (in short) caching the HTML with a placeholder and then replacing with a nonce value before serving it to the client, so it would be unique for each request. – Nick Jan 27 '21 at 11:20
0

It depends which server-side cache we're talking about as this has usually many layers. If your application server is caching HTML to save on expensive SQL queries and template processing, then you still can use nonces by modifying the output HTML on the way back. Your templates and in result the generated HTML may contain placeholders like this:

<script nonce="CSP_NONCE_PLACEHOLDER">
...
</script>

This can be happily cached by the application server for days without negatively impacting the CSP nonce protection.

The nonce is then generated dynamically on the web server and replaces the above placeholder without expiring the cached value:

<script nonce="ee4183bb7784017e0ab7d38ab7ef9eb3a75190e0e76ca5daba8cd20104bd8131">
...
</script>

I have been doing it for years on webcookies.org with the web application running on Django, caching in Redis and web server being Nginx. With the latter there are two options:

    sub_filter_once off;
    sub_filter CSP_NONCE_PLACEHOLDER $ssl_session_id;
kravietz
  • 412
  • 2
  • 7
  • 1
    Now the attacker can simply include `REPLACE_WITH_NONCE` as part of the exploit, right? The malicious script now gets the valid nonce as well. – Prinzhorn Jul 12 '17 at 16:54
  • 1
    right, but the "REPLACE_WITH_NONCE" is example string it can be more complex so more difficult to discover @Prinzhorn – BruceStackOverFlow Mar 10 '20 at 22:39