cure53 / DOMPurify

DOMPurify - a DOM-only, super-fast, uber-tolerant XSS sanitizer for HTML, MathML and SVG. DOMPurify works with a secure default, but offers a lot of configurability and hooks. Demo:
https://cure53.de/purify
Other
13.61k stars 695 forks source link

Error thrown with `style` tag in `svg` #900

Closed timonmasberg closed 7 months ago

timonmasberg commented 8 months ago

Background & Context

I am not quite sure if this is a bug or just me misunderstanding something, but when I use sanitize in my Trusted Types Policy, it will always throw Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'self' 'nonce-csp_nonce'". Either the 'unsafe-inline' keyword, a hash ('sha256-...'), or a nonce ('nonce-...') is required to enable inline execution.

image

This will get thrown once, even if I use it with FORBID_TAGS: ['style']. I don't really understand why the error occurs, since the parseFromString call is with a TrustedHTML

This is how my implementation looks:

globalThis.trustedTypes.createPolicy('default', {
        createHTML: (s) =>
            DOMPurify.sanitize(s, {
                USE_PROFILES: { html: true, svg: true },
                FORBID_TAGS: ['style'],
            }),
    });

If I remove the style tag before sanitizing, the error will not get thrown.

My trusted type headers are trusted-types angular angular#bundler dompurify default; require-trusted-types-for 'script'

Bug

Input

<svg viewBox="64 64 896 896" focusable="false"><defs><style /></defs><path d="M521.7 82c-152.5-.4-286.7 78.5-363.4 197.7-3.4 5.3.4 12.3 6.7 12.3h70.3c4.8 0 9.3-2.1 12.3-5.8 7-8.5 14.5-16.7 22.4-24.5 32.6-32.5 70.5-58.1 112.7-75.9 43.6-18.4 90-27.8 137.9-27.8 47.9 0 94.3 9.3 137.9 27.8 42.2 17.8 80.1 43.4 112.7 75.9 32.6 32.5 58.1 70.4 76 112.5C865.7 417.8 875 464.1 875 512c0 47.9-9.4 94.2-27.8 137.8-17.8 42.1-43.4 80-76 112.5s-70.5 58.1-112.7 75.9A352.8 352.8 0 01520.6 866c-47.9 0-94.3-9.4-137.9-27.8A353.84 353.84 0 01270 762.3c-7.9-7.9-15.3-16.1-22.4-24.5-3-3.7-7.6-5.8-12.3-5.8H165c-6.3 0-10.2 7-6.7 12.3C234.9 863.2 368.5 942 520.6 942c236.2 0 428-190.1 430.4-425.6C953.4 277.1 761.3 82.6 521.7 82zM395.02 624v-76h-314c-4.4 0-8-3.6-8-8v-56c0-4.4 3.6-8 8-8h314v-76c0-6.7 7.8-10.5 13-6.3l141.9 112a8 8 0 010 12.6l-141.9 112c-5.2 4.1-13 .4-13-6.3z" /></svg>

Given output

<svg viewBox="64 64 896 896"><defs></defs><path d="M521.7 82c-152.5-.4-286.7 78.5-363.4 197.7-3.4 5.3.4 12.3 6.7 12.3h70.3c4.8 0 9.3-2.1 12.3-5.8 7-8.5 14.5-16.7 22.4-24.5 32.6-32.5 70.5-58.1 112.7-75.9 43.6-18.4 90-27.8 137.9-27.8 47.9 0 94.3 9.3 137.9 27.8 42.2 17.8 80.1 43.4 112.7 75.9 32.6 32.5 58.1 70.4 76 112.5C865.7 417.8 875 464.1 875 512c0 47.9-9.4 94.2-27.8 137.8-17.8 42.1-43.4 80-76 112.5s-70.5 58.1-112.7 75.9A352.8 352.8 0 01520.6 866c-47.9 0-94.3-9.4-137.9-27.8A353.84 353.84 0 01270 762.3c-7.9-7.9-15.3-16.1-22.4-24.5-3-3.7-7.6-5.8-12.3-5.8H165c-6.3 0-10.2 7-6.7 12.3C234.9 863.2 368.5 942 520.6 942c236.2 0 428-190.1 430.4-425.6C953.4 277.1 761.3 82.6 521.7 82zM395.02 624v-76h-314c-4.4 0-8-3.6-8-8v-56c0-4.4 3.6-8 8-8h314v-76c0-6.7 7.8-10.5 13-6.3l141.9 112a8 8 0 010 12.6l-141.9 112c-5.2 4.1-13 .4-13-6.3z"></path></svg>

Which is also the expected output.

cure53 commented 8 months ago

Hmmm, not sure if I fully understand the question :slightly_smiling_face:

Does this only happen with style elements inside SVG or also inside HTML? If only for SVG, I would strongly assume that the browser treats style inside SVG as a XSS sink:

<svg>
<style><script>alert(1)</script></style>
</svg>
timonmasberg commented 8 months ago

Hmmm, not sure if I fully understand the question :slightly_smiling_face:

Does this only happen with style elements inside SVG or also inside HTML? If only for SVG, I would strongly assume that the browser treats style inside SVG as a XSS sink:


<svg>

<style><script>alert(1)</script></style>

</svg>

Yes exactly, but whenever I call sanitize, it does throw the error shown above (see the stacktrace starts at sanitize). I don't understand why this throws an error?

cure53 commented 8 months ago

That I don't know either :) Can you spin up a test case so we can have a look at it?

timonmasberg commented 7 months ago
image

I created a small reproduction: https://gist.github.com/timonmasberg/d87cb5bd320d7443cab803e1a4aeed05

Thanks once again for your help!

cure53 commented 7 months ago

Thanks for making this available.

I am a bit confused because I am not sure how the error in fact relates to Trusted Types and not simply CSP. What I get is a CSP error complaining about the usage if inline CSS.

Could you explain further how this might be a TT issue and not simply CSP complaining about inline CSS?

timonmasberg commented 7 months ago

Thanks for making this available.

I am a bit confused because I am not sure how the error in fact relates to Trusted Types and not simply CSP. What I get is a CSP error complaining about the usage if inline CSS.

Could you explain further how this might be a TT issue and not simply CSP complaining about inline CSS?

Yes sorry, ofc it is not a TT error, i was referring to it being thrown inside of the policy. Sorry for the misunderstanding. But what I still don't understand is, why the error is thrown inside of DOMPurify? Shouldn't it strip away the style tag complete (at least when using forbidden tags option)? Because for me the only fix is to "pre-sanitize" the string and pass it into DOMPurify. I would expect that this is also something done by the library.

cure53 commented 7 months ago

So, I think it's a plain CSP error message that only appears to show on Chrome (and other browsers with the same engine) but doesn't show on Firefox, for example - as my testing showed.

Googling this a bit seems to indicate that others have the same issue with Chrome being a bit overcritical here. Or Firefox not being critical enough, depending on the viewpoint :slightly_smiling_face:

I think this is not a DOMPurify issue or anything we can actually fix. You could fix it by relaxing the CSP for CSS maybe?

timonmasberg commented 7 months ago

So, I think it's a plain CSP error message that only appears to show on Chrome (and other browsers with the same engine) but doesn't show on Firefox, for example - as my testing showed.

Googling this a bit seems to indicate that others have the same issue with Chrome being a bit overcritical here. Or Firefox not being critical enough, depending on the viewpoint 🙂

I think this is not a DOMPurify issue or anything we can actually fix. You could fix it by relaxing the CSP for CSS maybe?

Hm relaxing CSP would mean allowing all inline scripts. I just thought that DOMPurify would be able to handle this and strip everything away, but it appears that Chrome doesn't even like that. I guess i stick to "pre-"sanitizing it by removing the style tag myself...

Thanks