Skip to content
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

Referencing SVGs through USE from other domains #707

Closed
waterplea opened this issue Jul 1, 2019 · 29 comments
Closed

Referencing SVGs through USE from other domains #707

waterplea opened this issue Jul 1, 2019 · 29 comments

Comments

@waterplea
Copy link

Currently, trying to host SVGs with symbols on CDN and then using them on your page through USE tag to allow color changes with currentColor results with error: Unsafe attempt to load URL. There is a bug for chromium suggesting it should follow CORS policies providing ability to allow such references:
https://bugs.chromium.org/p/chromium/issues/detail?id=470601

There was a suggestion to add crossorigin attribute to USE but it seems that specs only define it on IMAGE or SCRIPT:

https://svgwg.org/svg2-draft/linking.html#processingURL-fetch

Please have a look at it. Seems to me that it would be a lot safer to use SVGs like that rather than loading them with network request and inlining in the page which is a current workaround if you want to control the color.

@AmeliaBR
Copy link
Contributor

AmeliaBR commented Jul 1, 2019

I agree that this is important. It is a significant limitation for SVG the crossorigin use references aren't supported. I think you make a good point, that this encourages less safe practices by authors.

When the crossorigin attribute was originally added to SVG, <use> was included. It was removed in 2015 because of concern about the details about how <use> imports should work. But even then, the plan was to add it back in eventually. (See discussion minutes & resolution)

Many of the issues that were brought up in that discussion (about how the use element shadow DOM model should work & how external files should be parsed) have since been resolved (although the current spec text doesn't reflect all the resolutions that have been made in other issues). So it may be worth reconsidering.

@waterplea
Copy link
Author

I'm not a security expert, I tried USE with external SVGs on the same domain and it seems that scripts are not run, neither event handlers like onclick trigger and other basic malicious scripting I could think of. I realize there is more danger there that I do not know about, but like I said, people currently work around this by simply requesting SVG source and inlining it into the page and I doubt many of them run it through DOMPurify or something. So even if it might be a not that safe practice, to achieve the same effect people most likely turn to an even more dangerous solutions.

Glad to see it's not dismissed completely, hope you can think of something!

@AmeliaBR AmeliaBR self-assigned this Jul 15, 2019
@css-meeting-bot
Copy link
Member

The SVG Working Group just discussed Referencing SVGs through USE from other domains, and agreed to the following:

  • RESOLUTION: Add cross-origin attribute to the <use> element in a current or future spec
  • RESOLVED: Add cross-origin attribute to the <use> element in a current or future spec
  • RESOLVED: Add the cross-origin attribute to the <use> element to SVG 2, and mark it at-risk
  • RESOLVED: Request implementation feedback about the cross-origin attribute to the <use> attribute
The full IRC log of that discussion <myles> Topic: Referencing SVGs through USE from other domains
<myles> GitHub: https://github.com//issues/707
<myles> AmeliaBR: Should we add a cross origin attribute to the use element.
<myles> AmeliaBR: Right now, none of the browsers support <use> references to cross-origin files. But they do support it to the same origin.
<myles> AmeliaBR: When SVG introduced the cross-origin attribute for <image> and <script>, it was added to <use> but it got pulled back because it was unclear how it would work with shadow dom, and how that would affect cross-origin. I think that is cleared up now. The way we agreed that <use> should be a closed shadow dom where you can't access the internals
<myles> krit: I don't think we have consensus on that
<myles> AmeliaBR: I thought we agreed? I can dig up the issue
<AmeliaBR> https://github.com//issues/363
<myles> AmeliaBR: Everyone agrees.
<myles> AmeliaBR: But! Neither of those really make a difference. All those complications would be the same. The use case brought up in this new issue makes a good point, that because cross-origin <use> isn't supported, the workaround that authors have to use is to fetch the cross-origin file with script, and then inject the markup directly in their page, because this is less-secure than <use> cross references, we say things like "don't run scripts"
<myles> krit: But if there is a less-secure method, then providing a more-secure method isn't necessarily a win for the users
<myles> AmeliaBR: There are two risks. 1) Allowing the current webpage access to the content from the other domain, but I'm not suggesting that we should allow free origin; it should be based on CORS
<myles> AmeliaBR: This is security for the webpage author when you're referencing a 3rd party domain, where the content on that 3rd party domain might change.
<myles> AmeliaBR: We get a little bit of extra security if the page author opts into it. Like CSP.
<myles> AmeliaBR: Also, it's easier for the author (less lines of code)
<myles> krit: We already define cross-origin attribute for other elements. Specification-wise, it wouldn't be a big deal to add it. Do you think implementations would implement it? Or should we move it to SVG 2.1.
<myles> AmeliaBR: I'd like to resolve that we'd like to add this, but then ask implementors whether they think it can come in the short term or whether it should be delayed
<myles> krit: Any concerns for adding the cross-origin attribute to <use>?
<myles> <silence>
<myles> RESOLUTION: Add cross-origin attribute to the <use> element in a current or future spec
<myles> RESOLVED: Add cross-origin attribute to the <use> element in a current or future spec
<myles> krit: Since we resolved on that part, we can at least have a note with our intentions into SVG 2.
<myles> AmeliaBR: Sure. We can add a note and open issue, requesting implementor issue
<myles> krit: That's part two. For now, let's resolve on a note.
<myles> <some general discussion about the merits of a note vs normative text>
<myles> AmeliaBR: We should start the request for feedback right away, on the issue therad.
<myles> *thread
<myles> RESOLVED: Add the cross-origin attribute to the <use> element to SVG 2, and mark it at-risk
<myles> RESOLVED: Request implementation feedback about the cross-origin attribute to the <use> attribute

@AmeliaBR
Copy link
Contributor

@fsoder @longsonr @litherum Consider this a request for feedback (please pass on to whichever colleague can best answer):

How easy/difficult would it be to make <use> cross-origin, with crossorigin controls? The default behavior (no attribute) would still be to block cross-origin requests. Processing of the external file would be the same as for same-domain external <use> references.

@longsonr
Copy link

longsonr commented Jul 15, 2019

I'm waiting on other implementers to do image and FEImage. I assume they'd be easier.

Not sure we'd implement crossorigin for <use> given the existence of open redirectors.

@AmeliaBR
Copy link
Contributor

the existence of open redirectors.

I'm not sure what you mean. In the sense that a <use> reference to one file can then trigger references to other files?

@fsoder
Copy link

fsoder commented Jul 15, 2019

It shouldn't be too difficult if there are no additional restrictions to consider (integration with CSP?).

@waterplea
Copy link
Author

waterplea commented Aug 14, 2019

So what is the next step now? Chromium bug to support it is on hold until specs are established. @longsonr you haven't clarified what you meant by dangers of open redirectors.

@longsonr
Copy link

@AmeliaBR
Copy link
Contributor

@longsonr Can you explain which part of that issue is relevant? (There's 9 years of comments & much of it is out of date).

Conforming SVG-as-image loads shouldn't be allowed to make <use> references to other files, same origin or not. (SVG as image should never trigger additional file fetches of any type.) If the SVG is loaded as an active document (iframe, object, view image in its own tab), then cross-origin pings to other domains can already happen using <image>, as in the original example in that thread, so cross-origin <use> doesn't add an extra risk. (Unless the hosting domain is sanitizing the SVG files for crossorigin href on some elements but not on others. But I don't know of any such file scrubbers.)

@Malvoz
Copy link

Malvoz commented Sep 15, 2019

(integration with CSP?).

Related directive proposal: w3c/webappsec-csp#198

Edit: w3c/webappsec-csp#199

@css-meeting-bot
Copy link
Member

The SVG Working Group just discussed Referencing SVGs through USE from other domains, and agreed to the following:

  • RESOLVED: defer cross origin use element references to post-SVG 2
The full IRC log of that discussion <heycam> Topic: Referencing SVGs through USE from other domains
<heycam> github: https://github.com//issues/707
<heycam> AmeliaBR: cross origin use elements
<heycam> ... right now, use elements can clone from the same file, or from a different file on the same domain. we do have good support for both of those
<heycam> ... we have no way of cloning from a file on another domain, which is problematic for people who use CDNs for static assets
<heycam> krit: we already resolved to move that to SVG 2, but Blink is waiting for feedback if they can implement it
<heycam> AmeliaBR: Robert Longson, Mozilla contributor, pointed out other browsers haven't supported <image>, <feImage>, cross origin references
<heycam> ... so shouldn't count on them doing it for <use>
<heycam> ... but we did have fsoder on the Chromium team saying it shouldn't be too difficult to consider
<heycam> emilio: from Opera
<heycam> krit: do we stand by our resolution to defer?
<heycam> AmeliaBR: we all agree it's desired, but should it be in SVG 2
<heycam> myles: are there implementations?
<heycam> emilio: no
<heycam> myles: then it shouldn't be in SVG 2
<heycam> emilio: what are the security implementations? not confident enough about that
<heycam> AmeliaBR: it's similar to other active content references, cross origin filters
<heycam> emilio: but cross origin use elements insert content inside the host document
<heycam> ... it's not the same as just applying a filter
<heycam> emilio: if you leave the foreignObject details as is, that could be a security issue
<heycam> AmeliaBR: the other things we strip are things like scripts
<heycam> emilio: scripts only run once, so the clone knows the script has already run
<heycam> AmeliaBR: and you don't scripts in the external file
<heycam> ... but security things would need to be spelled out clearly
<heycam> emilio: someone should do a security audit of the feature
<heycam> ... cross origin filters, didn't want we want to remove them?
<heycam> mstange: it's come up again and again
<heycam> ... this is filter on cross origin iframes
<heycam> ... nobody has suggested removing cross origin images referenced by feImage
<heycam> AmeliaBR: the closest thing here is something like HTML Imports, cloning content into the DOM from another file
<heycam> ... even for that reason, let's wait for the HTML folks to figure out the security concerns here
<heycam> ... and we really need to get SVG 2 stabilized
<heycam> ... minutes from Jul 16 had 3 different solutions
<heycam> ... we'll go back to the first one: add cross origin use references to a future spec, rather than in SVG 2 and at risk
<heycam> krit: I would rather let us defer the entire feature
<heycam> AmeliaBR: so override our July resolution to put it in the spec as at risk, and just say we'd like to it, but not in SVG 2. maybe add a note to authors/implementors in the spec
<heycam> krit: could also be done in the CG
<heycam> RESOLVED: defer cross origin use element references to post-SVG 2
<AmeliaBR> All text issues: https://github.com/w3c/svgwg/issues?q=is%3Aopen+is%3Aissue+label%3A%22Text+chapter%22
<AmeliaBR> Two tagged internationalization: https://github.com/w3c/svgwg/issues?q=is%3Aopen+is%3Aissue+label%3Ai18n-tracking

@tigrr
Copy link

tigrr commented Apr 20, 2020

The same problem when trying to use a cross-origin SVG from CSS. E. g. if a page at example.com loads a stylesheet at static.example.com/style.css and the stylesheet references an image at static.example.com/image.svg, the image is blocked.

crossorigin attribute won't be applicable here.

@Malvoz
Copy link

Malvoz commented Apr 20, 2020

@tigrr The CSS crossorigin URL modifier is to be defined by CSSWG, see w3c/csswg-drafts#1603.

@SebastianZ
Copy link

Just stumbled over this issue after asking on Stack Overflow how to get cross-origin references in <use> elements to work.

Somehow expected CSP headers to cover all such cases automatically.

Sebastian

isabroch added a commit to solizzy/timelineTracker that referenced this issue Mar 31, 2021
<use> does not allow CORS (w3c/svgwg#707)
so inject the svg data with each instance
causes slight performance hit but cleans up html
@waterplea
Copy link
Author

It's been almost a year, SVG2 is still a draft and this much needed feature is still postponed to "post-SVG2". Is there something we can do to speed things up regarding this matter?

@longsonr
Copy link

@waterplea yes, provide an implementation for Chrome and Firefox. Two implementations pretty much guarantees it will be in an updated specification. You might want to implement CORS for SVG image elements first as that's likely easier. In either case creating WPT testcases would be where you'd start, then you can test your implementations once you've completed them.

@waterplea
Copy link
Author

@longsonr I'm not working on Chrome :) I came here because bug for Chrome to implement this in on halt "until this is in the specs":
https://bugs.chromium.org/p/chromium/issues/detail?id=470601

Maybe somebody from SVG WG can step in there and say that in this case specs would follow the implementation?

@longsonr
Copy link

@waterplea Specs reflect reality. If there are implementations then the spec will change. You asked how to move this forward. The Chrome bug won't proceed unless there's commitment for implementation in another browser. If you commit to do a Firefox implementation that would unblock the Chrome implementation.

@waterplea
Copy link
Author

I've created a Firefox bug if that's of any help:
https://bugzilla.mozilla.org/show_bug.cgi?id=1724903

@longsonr
Copy link

longsonr commented Aug 10, 2021

@waterplea I'm afraid it isn't unless you're prepared to implement it. When you said is there something we can do to speed things up, what were you suggesting?

@shhnjk
Copy link
Member

shhnjk commented Dec 16, 2022

I'm not a security expert, I tried USE with external SVGs on the same domain and it seems that scripts are not run, neither event handlers like onclick trigger and other basic malicious scripting I could think of. I realize there is more danger there that I do not know about, but like I said, people currently work around this by simply requesting SVG source and inlining it into the page and I doubt many of them run it through DOMPurify or something. So even if it might be a not that safe practice, to achieve the same effect people most likely turn to an even more dangerous solutions.

Replying to an old comment.
While script elements are inert, event handlers or link with javascript: URLs work. Here is the PoC which should execute script in Chrome/Firefox/Safari. Which shows that the SVGUseElement is not a safe alternative.

Additionally, I think that the ability to import external script or html into current document has been only granted to places where script can be executed (i.e. script.src, import(), etc). AFAIK, SVGUseElement is the only place where we still allow this. This has led to bypass of several security sanitizers and linters (e.g. Trusted Types, Sanitizer API).

Therefore, I'm working to removing support for data: URLs in SVGUseElement, and I would love to keep the current behavior of only allowing same-origin resources in SVGUseElement.

@waterplea
Copy link
Author

waterplea commented Dec 17, 2022

@shhnjk thank you for this example. The problem remains though, for many years — there is no way to simply color an svg icon on the CDN with CSS and it's extremely sad.

@ydaniv
Copy link

ydaniv commented Dec 17, 2022

@waterplea you'll be able to when CSS custom properties with SVG params will be allowed, already resolved by CSSWG to be speced, see: https://tabatkins.github.io/specs/svg-params/#setting

@waterplea
Copy link
Author

@waterplea you'll be able to when CSS custom properties with SVG params will be allowed, already resolved by CSSWG to be speced, see: https://tabatkins.github.io/specs/svg-params/#setting

Awesome! Thank you for sharing.

@shhnjk
Copy link
Member

shhnjk commented Dec 18, 2022

Can we close this issue then?

I don't think we should allow cross-origin resources in SVGUseElement, and if there is such a need, things like HTML Modules is probably a better way of importing cross-origin resources.

@waterplea waterplea closed this as not planned Won't fix, can't repro, duplicate, stale Dec 18, 2022
@waterplea
Copy link
Author

I wish it would move a bit faster though, that SVG props proposal is 4 years old already and this functionality seems rather basic and very much needed across the web.

@ydaniv
Copy link

ydaniv commented Dec 19, 2022

That's the old unofficial draft. A new official one should be added for svg-params, don't remember where it stands now, I think @tabatkins is still the editor.

@shhnjk
Copy link
Member

shhnjk commented Jan 9, 2023

That's the old unofficial draft. A new official one should be added for svg-params, don't remember where it stands now, I think @tabatkins is still the editor.

Looks like it's now called CSS Linked Parameters 🙂

cjpillsbury added a commit to muxinc/media-chrome that referenced this issue May 11, 2023
Working version here:
https://media-chrome-docs-git-fork-cjpillsbury-docs-styling-guide-mux.vercel.app/en/styling

First pass on a styling guide. 
I dropped the external svg example (`<svg><use
href="#ref"></use></svg>`) because, although it works, there was not a
clean way to include it in sandpack, and the most recent plan (host
externally) also [has issues](w3c/svgwg#707).

Time permitting, I'd like to also add a section on Styling + WCAG /
A11Y, but wanted to make sure we get through any remaining planned
updates before expanding on scope even more.

---------

Co-authored-by: Dave Kiss <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests