vue icon indicating copy to clipboard operation
vue copied to clipboard

Avoid inline styles in server-side directives (SSR) to allow nonce-based CSPs

Open aKzenT opened this issue 3 years ago • 8 comments

What problem does this feature solve?

Currently when using the v-show directive server-side it produces style="display:none;" attributes on HTML elements. These collide with using a nonce-based CSP (content security policy level 2) setup as CSP Level 2 does not have a method to whitelist inline style attributes. CSP Level 3 allows this by using 'unsafe-hashes' and whitelisting the hash-value of the generated style attribute, but is not supported yet by all browsers (e.g. Safari). This makes it currently impossible to use a nonce-based CSP when using v-show and server-side rendering.

What does the proposed API look like?

E.g. Allow configuration of a custom class name that is used by v-show instead of the inline-styles.

aKzenT avatar Jan 12 '21 12:01 aKzenT

Not sure what is the exact problem here and what cannot be achieved but the proposed solution using a custom class name for v-show looks more like a patch.

Is this what you are looking for https://github.com/vuejs/vue/pull/11826 ?

posva avatar Jan 12 '21 13:01 posva

Not exactly. The referenced issue is about adding nonces to generated style or script element. While also an important aspect in complete CSP support, it does not solve the issue described here which is about inline style attributes.

Inline Attributes (style='') cannot be whitelisted with nonces because nonces only work on <style> and <script> elements, not on individual attributes. The usual guideline is therefore to never use inline-style-attributes at all and use other means instead. Note that you can still set style properties via javascript as the CSP tries to protect against injections into the DOM itself. However in the case of SSR this does not help obviously as the style-attributes need to be transferred to the client somehow.

aKzenT avatar Jan 12 '21 14:01 aKzenT

@aKzenT

Preventing inline styles is a pretty strict CSP directive, I'd only recommend this setting in highly secure settings.

An alternative is to do a hash of the style content that v-show produces and add that as a safe value. This will mean you don't need to specify the nonce wherever v-show may appear.

I'd still highly recommend allowing inline styles, especially if you have a strict CSP policy for scripts. As far as I know scripting would be required to inject inline styles, so I can't see the benefit of preventing inline styles at this stage.

blake-newman avatar Feb 01 '21 23:02 blake-newman

I think you are mostly right. However there are some problems with this approach:

Using hashes for inline-attributes is a CSP Level 3 feature and requires the 'unsafe-hashes' attribute, which is not supported in Safari for example. This leaves you no other choice than falling back to domain whitelists and 'unsafe-inline' for styles. Domain whitelists are hard to maintain however and can open security vulnerabilities e.g. when whitelisting CDNs too broadly.

aKzenT avatar Feb 02 '21 22:02 aKzenT

@aKzenT indeed which is why I recommend just allowing unsafe-inline for styles. Especially if your scripts are safely protected as this is the main entry point to injections of styles. So without the ability to embed harmful scripts they can do little with styles.

https://csp-evaluator.withgoogle.com/

Even enabling unsafe-eval for styles isn't a red flag when valuated.

I would say that if you really care for protection against styles then I'd question the use of any dependency in your project as they pose more risk than inline styles.

blake-newman avatar Feb 03 '21 08:02 blake-newman

Are you suggesting to not use any CSP rule for styles (just allowing everything)? Or do you still see a value in using a domain whitelist? Because it's not possible to use a 'nonce' for external styles and 'unsafe-inline' for attributes. Using nonces automatically disables 'unsafe-inline'.

We will probably take the route of using a domain whitelist for now, but this is a configuration PITA because we already have all the infrastructure to propagate nonces through all loaded scripts and styles, but we would still need to change to domain whitelists as 'unsafe-inline' does not support anything else in combination.

aKzenT avatar Feb 04 '21 17:02 aKzenT

Our CSP policy for style is 'self' https: 'unsafe-inline' - it works well for us and should for most cases. As-long as the scripts have a safe policy then no foul play can occur.

blake-newman avatar Feb 04 '21 18:02 blake-newman

我们的 CSP 风格政策是'self' https: 'unsafe-inline'- 它对我们很有效,并且应该适用于大多数情况。只要脚本有一个安全的策略,那么就不会发生犯规。

thanks a lot you are a good man

lywufei avatar Feb 15 '22 06:02 lywufei