[CSP] Blocks the use of style attributes inside SVG without generating console errors




3 years ago
28 days ago


(Reporter: April, Unassigned)


(Blocks: 2 bugs)

Firefox Tracking Flags

(Not tracked)


(Whiteboard: [domsecurity-backlog], URL)


(3 attachments)



3 years ago
Created attachment 8739043 [details]

On my website (https://pokeinthe.io), I had an issue where SVG icons were frequently rendering in pure black, instead of with color.  They are generated by my design program (Affinity Designer) and look like this:

> <?xml version="1.0" standalone="no"?>
> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
> <svg width="100%" height="100%" viewBox="0 0 256 250" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;">
>     <path d="..." style="fill:rgb(246,188,246);fill-rule:nonzero;"/>
> </svg>

In particular, they have something like these style attributes:

> style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;"
> style="fill:rgb(246,188,246);fill-rule:nonzero;"

It took me a long time to figure out what was happening.  It turns out it was due to my site-wide CSP policy:

> Content-Security-Policy:
>   default-src 'none';
>   child-src https://air.mozilla.org;
>   font-src 'self' https://fonts.gstatic.com;
>   frame-ancestors 'none';
>   frame-src https://air.mozilla.org;
>   img-src 'self';
>   media-src 'self';
>   script-src 'self';
>   style-src 'self' https://fonts.googleapis.com

It turns out that Firefox was treating these SVG files as having 'unsafe-inline' and thus blocking the loading of those attributes.  Unfortunately, as you can see in the screenshots, there is no indication that this is happening in the console (black-svg-due-to-csp-no-error-in-console.png). It's in fact *doubly* confusing, because it looks perfectly fine in the network tab (confusing-network-tab.png). To be honest, it's actually *triply* confusing, because Chromium browsers have no problem with these SVG files at all, and so there were no leads in their dev tools either.

The only way I could fix it was enabling a custom CSP header just for SVG files (colored-svg-due-to-custom-csp-policy-for-svg.png).

> default-src 'none'; frame-ancestors 'none'; style-src 'self' 'unsafe-inline'

Inside nginx:

> add_header Content-Security-Policy "default-src 'none'; child-src https://air.mozilla.org; font-src 'self' https://fonts.gstatic.com; frame-ancestors 'none'; frame-src https://air.mozilla.org; img-src 'self'; media-src 'self'; script-src 'self'; style-src 'self' https://fonts.googleapis.com";
> location ~ \.svg$ {
>     add_header Content-Security-Policy "default-src 'none'; frame-ancestors 'none'; style-src 'self' 'unsafe-inline'";
> }

See: https://github.com/w3c/webappsec-csp/issues/45 for related discussion.

Comment 1

3 years ago
Created attachment 8739045 [details]

Comment 2

3 years ago
Created attachment 8739046 [details]
Whiteboard: [domsecurity-backlog]
Blocks: 1242016
Duplicate of this bug: 1312240

Comment 4

2 years ago
Pasting/updating my description from bug 1312240:

We recently implemented CSP on gimp.org the most secure way, i.e. without 'unsafe-inline': https://observatory.mozilla.org/analyze.html?host=www.gimp.org

Actual results: We had a small Wilber icon in the top (just left to "GIMP" item in the top black bar) and it ended up black (hence barely visible) because the style is fully inline (as any SVG file straight out of Inkscape): https://www.gimp.org/
It was not spotted until recently (SVG images passed under the inline script/css cleaning radar). All other SVG images used on our website have the same issue.

Note that I found a workaround for the time being: since our styling needs are mostly basic, I could convert all inline CSS into XML attributes ("Optimized SVG" export in Inkscape) with minimal loss, then I clean out all remaining style with a regexp. But this is far from an optimal workflow to have to process every SVG image through an export then do additional cleaning.


Expected results:
I checked the CSP spec and according to section "3.6 Policy Applicability", when a SVG is embedded via <img>:

> No policy; should be just as safe as JPG

So if not mistaken, in our case, since the Wilber icon is indeed included as <img>, Firefox should not apply any policy on the subresource, hence it should apply the inline CSS in the SVG icon.

Also I can confirm that it works as requested by the spec in Chrome: the CSP policy is applied if I display the SVG standalone for instance (no styling, it becomes dark: https://www.gimp.org/images/wilbericon.svg), but it appears ok, with styling, when used as `<img>` (in gimp.org).
Duplicate of this bug: 1315427

Comment 6

2 years ago
This is affecting portswigger.net too. We aren't comfortable with enabling unsafe-inline for styles as a workaround, as this opens up a lot of attack surface.
Priority: -- → P3
Duplicate of this bug: 1381127


11 months ago
Duplicate of this bug: 1410730


7 months ago
Duplicate of this bug: 1405725


7 months ago
Duplicate of this bug: 1443435
The language from comment 4 doesn't seem to be in the current CSP spec draft at https://w3c.github.io/webappsec-csp/ nor in https://www.w3.org/TR/CSP3/

That said, looks like CSP is only honored on documents in browsing contexts in general (per https://w3c.github.io/webappsec-csp/#initialize-document-csp which is only called from the HTML spec during navigation).

Christoph, is my understanding there correct?  If so, why are we applying CSP to SVG images loaded via <img> at all?
Flags: needinfo?(ckerschb)
(In reply to Boris Zbarsky [:bz] (no decent commit message means r-) from comment #11)
> Christoph, is my understanding there correct?  If so, why are we applying
> CSP to SVG images loaded via <img> at all?

Your understanding is absolutely correct. As far as I can tell this is simply a bug in our implementation and we should eventually fix it.
Flags: needinfo?(ckerschb)
You need to log in before you can comment on or make changes to this bug.