Closed andrewmenich closed 1 year ago
Hey @andrewmenich . This is a difficult problem to solve. When the cache is enabled the request is dealt with directly by the caching layer, so there's no opportunity for us to run additional logic if a cached result is being served.
The way we'd normally get around this with other dynamic content (such as CSRF tokens) is to pull it in via an ajax request, but in this circumstance any JS code would need to be tagged with the nonce before it can be executed, including any ajax requests, so the ajax approach wouldn't work.
That leave us with the only option being to add the nonce as part of returning the cached content. In our case that would need to be done within our static caching layer and would need to be some sort of lua script thing which looked for specific tags in the HTML content and injected a nonce value into it, which would be difficult 🙈
However, I've had a read around other people facing the same problem and I largely agree with this answer on StackOverflow:
https://serverfault.com/a/1064775
Our caching layer will cache both the response headers and html content, which are the bits that need to match up for the nonce to do its work. If the page content is cached, then we know that no user content is being injected, so we don't need to worry about the nonce not changing when a cached page is served, because nobody can inject anything into it anyway.
As long as the responses coming from Craft have a random nonce set, then everything should work and remain secure.
Thank you for the detailed reply. It's good to get additional confirmation that this is an effective / valid approach. Cheers!
We've been tasked with adding a Content Security Policy to one of our sites hosted on Servd with static caching enabled. We'd like to use nonces in our policy but the caching would undermine the nonce. Would it be possible/make sense to have a feature in this plugin that could inject a nonce similar to how CSRF tokens are handled but with some kind of string or variable that would be replaced automatically on each request?