Baroshem / nuxt-security

🛡 Automatically configure your app to follow OWASP security patterns and principles by using HTTP Headers and Middleware
https://nuxt-security.vercel.app/
MIT License
737 stars 56 forks source link

Add csp policy in HTML #459

Closed GalacticHypernova closed 4 weeks ago

GalacticHypernova commented 1 month ago

Is your feature request related to a problem? Please describe.

It would be nice to also include the csp http-equiv meta tag in the document.

Describe the solution you'd like

After the csp is generated, we can store it and append it to the html. Since nuxt never hard-reloads itself, the head tags will stay.

Describe alternatives you've considered

Additional context

It would be a good idea to postpone this until after the current cheerio refactor lands, due to its low priority

vejja commented 1 month ago

We already do it for SSG, but not for SSR However there is no need to do it for SSR because in that case we transmit the CSP via headers Is there a specific use case you’d like to cover ?

GalacticHypernova commented 1 month ago

I'm concerned about legacy features (which are surprisingly not that uncommon) that may require specific adjustments, or certain CDN's/proxies that may alter headers if configured incorrectly. It's not for additional functionality per se, but it's more so a fallback measure to still enforce the policy in case something happens

vejja commented 1 month ago

The fundamental issue is that nonce can only be sent via headers.

GalacticHypernova commented 1 month ago

Well, what if the html policy would be slightly less restrictive? The default http header configuration for example already adds unsafe-inline, if the html policy will be more permissive it would still use the http policy unless not present, in which case the fallback policy will be enforced.

vejja commented 1 month ago

I think it is a bit tricky to have one CSP in headers, and a different one in http-equiv. The user is defining one single CSP and is not expecting to have a dual version with a more permissive one in http-equiv. I do understand the 'fallback' logic but I believe we should only go this way if we are able to provide the exact same CSP via html on top of headers.

In addition I'm wondering under which conditions it would be useful:

If we are concerned about enforcing CSP in case headers are modified by a malevolent actor, this becomes very interesting in theory but then how do we ensure that the same malevolent actor is not modifying the http-equiv ? If a fraudulent proxy can modify headers, it can also modify the HTML on the fly. This goes way beyond the CSP requirements, which mostly address XSS issues. Avoiding MTM is in the hands of SSL encryption, and we can't expect to mitigate MTM via CSP duplication.

GalacticHypernova commented 1 month ago

True, but in most cases it's way easier to notice and identify the root cause of html rewrites than header rewrites. For example, in CloudFlare alone there are at least 4 different features that can be used to alter headers. I wholeheartedly agree that it's up to the user to make sure their configuration is right, but it can be extremely challenging and there are ways to aid in it (kind of like anti-pattern detection).

how do we ensure that the same malevolent actor is not modifying the http-equiv ?

Theoretically we can use SRI to keep a copy of the policy along with the application code and then compare the 2 policies, if the hash isn't identical the browser will reject it, the app will break, and the rewritten html won't be effective. That's only one way to go about this, which I'm curious to hear your opinion about

vejja commented 1 month ago

Theoretically we can use SRI to keep a copy of the policy along with the application code and then compare the 2 policies, if the hash isn't identical the browser will reject it, the app will break, and the rewritten html won't be effective. That's only one way to go about this, which I'm curious to hear your opinion about

SRI can only block external assets loaded by the master HTML document, not the document itself. What's protecting the original HTML against rewrites is SSL.

To be clear, I'm not advocating against duplication of the CSP in http-equiv. I'm only saying that a correct implementation will be extremely difficult to achieve, for a use case that is not obvious to formulate.

GalacticHypernova commented 4 weeks ago

I'm only saying that a correct implementation will be extremely difficult to achieve, for a use case that is not obvious to formulate.

Well, I do like me a good challenge. New idea, how about adding a new runtime config variable and a runtime hook that would trigger once the ssr render has completed and compares it with the html?

vejja commented 4 weeks ago

😂💚 Excellent !!! I'm not sure I understand where you are going, but love it anyways 👏

To elaborate a bit more on my previous comment and explain where I was coming from

Up to this point, feature seems possible at the expense of additional CPU overhead on every SSR route, but why not ? Now issues that make it very complex:

Not impossible though, but definitely a lot of work

GalacticHypernova commented 4 weeks ago

at the expense of additional CPU overhead on every SSR route, but why not ?

Yea, that would be minimal, wouldn't cause any trouble.

reconciling the 2 code paths, i.e. merging SSR and SSG features. They belong to different nitro plugins

How about extracting the functionality to a shared util? That way the logic could be repeated for both SSR and SSG cases. If I understood all the issues you pointed out, that should fix 3 of them, as it will have the same behavior, we won't need the none-{{nonce}} placeholder because we could dynamically add the hashes.

vejja commented 4 weeks ago

Sounds like you could be right actually. Shall we move this to discussion until @Baroshem returns ?

GalacticHypernova commented 4 weeks ago

Sure thing!