I am not getting any response to any way I try to phrase this question, so I keep trying. I feel I've got to be missing something, but I've searched and searched. Why isn't it obvious? Why is it so hard to get an answer?
We are told we should use a Content Security Policy (CSP) nonce on our websites for inline scripts. The nonce should be randomly generated on the server for each request, and picked up by the website, then included via variable in the script tag. This way, we can guard against hacking.
Great, but I can find no way to do that, and still cache the website! Is there a way? Anybody?
If not, why isn't THAT specifically stated in one of these articles about creating CSP nonces? We need answers!
Thank you for letting me rant a bit. But seriously, what's the answer?
tl;dr: you can keep caching responses with nonces in them like you normally would, and CSP will still provide a strong defense against common XSS attacks.
This is an interesting question: when a page containing CSP nonces gets cached (in a public/back-end cache) that would result in the same nonce being transmitted to multiple users. This sounds bad, because nonces are not supposed to be reused. However, quite often this is not a problem in practice.
Let's say you as an attacker are served the same nonce as your victim on a response to the URL
/foo/bar
. Now you could use this nonce in your XSS payload. Let's consider two of the most common XSS scenario's:/foo/bar?payload=...
will likely have a different cache key than/foo/bar
, therefore causing the user to be delivered a fresh response with a new nonce. The attack fails./foo/bar
. However, if the user refreshes and gets a response from the cache, then this won't include your injected XSS payload. Alternatively, if they get a fresh response they will also get a fresh nonce. In either case the attack fails.Now, this doesn't mean that this situation can never be exploited: for example, if
/foo/bar
has vulnerable JavaScript that modifies the DOM in a way that the attacker payload can be injected it might possible to use the cached nonce. Think of DOM based XSS attacks via data in the#
segment of a URL or in AJAX responses.It will be much trickier for an attacker to exploit the latter situation though, which may be sufficient since the point of CSP is to just provide defense-in-depth; it can not guarantee immunity for 100% of XSS attacks.
If you still want to defend against this scenario: you can disable public caching for HTML responses. Private/browser caching is still fine, however, and you can also safely keep caching any non-HTML resources.