Which necessitates the unsafe-inline Content Security Policy directive, or another workaround. Can we get rid of the inline styling somehow?
Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'self'". Either the 'unsafe-inline' keyword, a hash ('sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU='), or a nonce ('nonce-...') is required to enable inline execution.
l.addStyleRule @ plotly__SHA256:3b219dbb9a6101432f4c65d4d4f35a0c5bff2ed2b9d43a007d46faa937b2ac81.mjs:7
plotly__SHA256:3b219dbb9a6101432f4c65d4d4f35a0c5bff2ed2b9d43a007d46faa937b2ac81.mjs:7 Uncaught TypeError: Cannot read property 'insertRule' of null
at Object.l.addStyleRule (plotly__SHA256:3b219dbb9a6101432f4c65d4d4f35a0c5bff2ed2b9d43a007d46faa937b2ac81.mjs:7)
at Object.1.../src/lib (plotly__SHA256:3b219dbb9a6101432f4c65d4d4f35a0c5bff2ed2b9d43a007d46faa937b2ac81.mjs:7)
at i (plotly__SHA256:3b219dbb9a6101432f4c65d4d4f35a0c5bff2ed2b9d43a007d46faa937b2ac81.mjs:7)
at plotly__SHA256:3b219dbb9a6101432f4c65d4d4f35a0c5bff2ed2b9d43a007d46faa937b2ac81.mjs:7
at Object.724.../build/plotcss (plotly__SHA256:3b219dbb9a6101432f4c65d4d4f35a0c5bff2ed2b9d43a007d46faa937b2ac81.mjs:7)
at i (plotly__SHA256:3b219dbb9a6101432f4c65d4d4f35a0c5bff2ed2b9d43a007d46faa937b2ac81.mjs:7)
at plotly__SHA256:3b219dbb9a6101432f4c65d4d4f35a0c5bff2ed2b9d43a007d46faa937b2ac81.mjs:7
at Object.12.../src/core (plotly__SHA256:3b219dbb9a6101432f4c65d4d4f35a0c5bff2ed2b9d43a007d46faa937b2ac81.mjs:7)
at i (plotly__SHA256:3b219dbb9a6101432f4c65d4d4f35a0c5bff2ed2b9d43a007d46faa937b2ac81.mjs:7)
at plotly__SHA256:3b219dbb9a6101432f4c65d4d4f35a0c5bff2ed2b9d43a007d46faa937b2ac81.mjs:7
at Object.20../aggregate (plotly__SHA256:3b219dbb9a6101432f4c65d4d4f35a0c5bff2ed2b9d43a007d46faa937b2ac81.mjs:7)
at i (plotly__SHA256:3b219dbb9a6101432f4c65d4d4f35a0c5bff2ed2b9d43a007d46faa937b2ac81.mjs:7)
at t (plotly__SHA256:3b219dbb9a6101432f4c65d4d4f35a0c5bff2ed2b9d43a007d46faa937b2ac81.mjs:7)
at plotly__SHA256:3b219dbb9a6101432f4c65d4d4f35a0c5bff2ed2b9d43a007d46faa937b2ac81.mjs:7
at plotly__SHA256:3b219dbb9a6101432f4c65d4d4f35a0c5bff2ed2b9d43a007d46faa937b2ac81.mjs:7
at plotly__SHA256:3b219dbb9a6101432f4c65d4d4f35a0c5bff2ed2b9d43a007d46faa937b2ac81.mjs:7
It's not entirely clear to me
a) what risks this rule is trying to mitigate, and
b) exactly which practices of ours would need to change to satisfy this rule.
Can you clarify?
If it's just using javascript to create and fill a <style> tag that's a problem (that's what Lib.addStyleRule is about) we could presumably stop using this - there's a fairly small set of rules we apply - and just apply these styles directly to the elements that need them.
Risks: https://stackoverflow.com/a/31759553/1175508
Note: Disallowing inline styles and inline scripts is one of the biggest security wins CSP provides.
Being suitable for a strict CSP environment is worthwhile. If not, Plotly often can鈥檛 be used in any such security-sensitive/modern app. Any unsafe CSP rules to work around Plotly鈥檚 behavior have to be applied to the HTTP response for a view of the app (HTML document) and not e.g. to the response for the Plotly library. So such a workaround adds risk when any untrusted input may be used to generate that HTML. So this bug and #897 are important to solve for e.g. enterprise web apps using Plotly.
To satisfy the no inline styling requirement, you need to neither apply CSS inline in attributes nor in style tags. The consumer of Plotly needs to load the CSS as a subresource (e.g. via a link tag). (Perhaps there鈥檚 another way as well?)
If library consumers not having to add a stylesheet link for Plotly is a requirement, and the styles themselves are required too, then alternatively Plotly should be able to manipulate the DOM to add a stylesheet link to the CSS on the same URL of the JavaScript library, with a css file name extension as postfix, to accommodate non-CDN consumers. But that would assume a certain CSP policy (script-src 'self'), so letting consumers add the stylesheet link to their documents themselves is better.
neither apply CSS inline in attributes
That's the one I'm worried about - if that means that we can't add style attributes to our elements, like:
<path d="M143.61,620V325.5H169.72V620Z"
style="vector-effect: non-scaling-stroke; opacity: 1; stroke-width: 0px; fill: rgb(31, 119, 180); fill-opacity: 1;"
></path>
then there's simply no possibility of plotly satisfying this requirement, ever. Many of these style attributes encode data values so it would not be possible to refer to some (static) style sheet to apply this styling.
We could get rid of Lib.addStyleRule but if that just pushes the error down to element style attributes, there's no point.
AFAIK you aren鈥檛 restricted to inline CSS even in SVG objects. See https://www.w3.org/wiki/SVG_Security#SVG_as_document_embedded_with_.3Ciframe.3E.2C_.3Cembed.3E_or_.3Cobject.3E
AFAIK you aren鈥檛 restricted to inline CSS even in SVG objects
I can't tell from that comment what you're proposing we should do?
I assumed it was clear, the solution would be to use external CSS as a subresource, either in the HTML document or the SVG itself. Added advantage is that optimization on the CSS will be easier (e.g. compression).
I assumed it was clear, the solution would be to use external CSS as a subresource
Right, but that's exactly what, as I said above, we cannot do:
Many of these style attributes encode data values so it would not be possible to refer to some (static) style sheet to apply this styling.
I suppose theoretically one could 1) figure out all the styles (colors, line widths, etc - could be many thousands of distinct values) needed for the data in your plot, 2) proxy that through some server to generate a style sheet, 3) apply classes instead of inline styles... but that would be a huge infrastructure cost (we're no longer a pure javascript library but it needs to be connected to a server) and performance cost, and frankly I don't see how that would be more secure - if the concern is that users might find some way to meddle with the javascript to generate malicious styles, this potential system seems like it would offer more, not fewer, opportunities for meddling.
I recognize the issue is challenging but I think you鈥檙e jumping to conclusions here. First of all CSS is theoretically meant be used for presentational details, not the semantics of the image. So it shouldn鈥檛 be necessary to apply CSS to get usable plots. But on to a more practical perspective ... The solution you picture is of course not feasible, and it鈥檚 not one I propose. I only propose to serve static CSS as subresource, and only as needed. For dynamic styling, those presentational parameters you identified so far can easily be replaced with equivalent SVG element attributes (color, stroke width).
For dynamic styling, those presentational parameters you identified so far can easily be replaced with equivalent SVG element attributes
Ah there we go, a concrete suggestion 馃憤Yes, if attributes are allowed we can consider changing all styles to attributes; I'm not sure if that would cover everything we need, but it should cover all of the data-linked attributes, ie those that cannot be handled by a static external CSS.
This would be a fairly large project; it would also make plotly.js deployment more involved, particularly for behind-the-firewall apps that require there to be no links to non-local resources, we'd need the location of the external CSS resource to be configurable.
As discussed in https://github.com/plotly/dash-core-components/issues/752 - it's apparently not the case that all inline styles are disallowed with strict CSP; just those set by providing the entire style attribute as a string. I don't know what D3 does, but if it accesses the style as an object as React apparently does, we may not need to convert everything to presentation attributes after all. We'd still need to get rid of Lib.addStyleRule and require the CSS to be loaded separately.
This could potentially be a build variant so that you'd only need the separate CSS with the CSP build, other users could continue using the single JS bundle.
FYI, injecting CSS that violates our CSP is a deal-breaker for our site.
Most helpful comment
As discussed in https://github.com/plotly/dash-core-components/issues/752 - it's apparently not the case that all inline styles are disallowed with strict CSP; just those set by providing the entire style attribute as a string. I don't know what D3 does, but if it accesses the style as an object as React apparently does, we may not need to convert everything to presentation attributes after all. We'd still need to get rid of
Lib.addStyleRuleand require the CSS to be loaded separately.This could potentially be a build variant so that you'd only need the separate CSS with the CSP build, other users could continue using the single JS bundle.