-
Notifications
You must be signed in to change notification settings - Fork 78
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Policy to allow only custom properties in inline CSS #174
Comments
The use case you describe fits well to nonces, but they are only supported for scripts. |
|
Ugh, Mondays. Thanks @mikewest. |
Thanks for the feedback.
Yes, I had that point too. But since we already have CSS Variables, hashes/nonces/sri and CSP in
I think that the way this would be implemented is not a nice practice. It would result in a server side function, that just read (and check) the user input and generate the nonce for it. So the nonce will always match the code snipped. This does not really add additional security and if the check fails (or the input is not checked at all) this results in the same problem as we have with With CSS Variables a user can only change the values of predefined properties, so this is much more restrictive policy and therefore preferable. |
I can not agree with this. If you supply a hash or a nonce for a piece of code (script or style), you're saying that it is not evil. |
If we could trust all sanitize functions, we would have no issues with code injection at all. |
I don't intend to address this in CSP3. I'm not sure it's a good idea in general, but I'll leave it open as a future feature request. |
@mikewest A better usecase is when using CSS variables to effectively whitelist dynamic CSS properties. It would allow JS to modify styles dynamically within reason. It wouldn't need a Also worth noting that this type of behavior can't be achieved with nonces or hashes. Here's a decent example: https://css-tricks.com/updating-a-css-variable-with-javascript/ And: https://eager.io/blog/communicating-between-javascript-and-css-with-css-variables/ |
The scripted setting examples in those articles work for me fine, either creating styles from nothing or altering variables in an inline block that has a nonce. @dav-is do you have a specific example of where this isn't working for you with a CSP? |
@dveditz You're right. I guess the initial styles need to be defined in the stylesheet, but changes can be applied to |
Same comment: manipulating CSS variables from JavaScript leads to use A lot of CSS tutos - even if I think this is a bad idea in a lot of cases - are doing this. An intermediary solution as |
I ran into a similar situation. I am using a nonce for my style and script tags, which I believe to be correct. If a user is able to inject into my page (but not my style/script), things are protected. Indeed, CSS variables make the situation tricky. A blanket .Thing { background: var(--theme-color); } // myElement.setAttribute('style', '--theme-color: black'); // Note: This parses the attribute which triggers CSP and will be blocked
myElement.style = "--theme-color: black;" // This parses the property, not the attribute. CSP is not invoked. It is not blocked. That JS block / workaround is awkward. After all, it is coming from trusted, nonced content. <div class="Thing" style="--theme-color: black"></div> This hopes to accomplish the same thing as my JS above, only it was done on the server while the page was being generated. But this will be blocked. And fair enough. How do we distinguish between a malicious user's injected styling and a trusted server side rendering?? Well, we already do that with nonce. What if I could: <div class="Thing" nonce="magic_nonce_value" style="--theme-color: black"></div> This opens a can of worms with nonce hijacking, though. Someone could craft an unclosed tag to gain the nonce and duplicate the style attribute: <div class="Malicious" style="malicious style"
<div class="Thing" nonce="magic_nonce_value" style="--theme-color:black"></div> It would extend the Is element nonceable? to include every tag type. And in multiple ways:
Preventing nonce hijacking and allowing nonce on any tag is the solution I prefer. Especially if the nonce can cascade to children. That gives me control over areas I have deemed safe from injection. |
Possibly half-answering my own question: The style tag can only appear in the head. And likely a user's injection will be in the body, not the head. However, a link tag to a stylesheet can appear in the body (it is body-ok: https://html.spec.whatwg.org/multipage/links.html#body-ok ). There is perhaps a related conversation going on in #212 . |
Introduction
A common challenge in a CMS to implement CSP is user defined styling.
Popular CMS allows the user to choose from a list of preserved templates and customize some basic colors or background images. Those custom values are usually served as inline CSS like the following example:
With the current draft I only see a few possibilities to make this working with CPS:
'unsafe-inline'
None of them seems to be a nice practice.
Goal
A nice solution would be to only allow custom properties as inline CSS. This allows to read user defined styles without the risk of malicious CSS injection:
Proposal
I propose to call this policy
'unsafe-variables'
or'inline-variables'
, but I'm sure that they are better names for it. So a CSP header for this would look like:(Note that in this case the use of the variables would be defined in a static CSS stylesheet on
'self'
)Further thoughts
For additional security, the policy could restrict the custom properties to a specific prefix (like
--user
) or selector (like:root
). This would allow to avoid overwriting properties used by the CMS itself:Inline variables in JS
This policy may be also used for
script-src
, but of course this is much more risky. So at least a restriction to a specified prefix should be required if this policy will be also considered for JS.Risk
Using this policy would not be completely without any risk, especially together with
'unsafe-eval'
, but it could help to decrease the usage of'unsafe-inline'
for CSS.The text was updated successfully, but these errors were encountered: