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

[svg] Is there any way we could allow SVGs to link to other files? #10481

Open
LeaVerou opened this issue Jun 21, 2024 · 18 comments
Open

[svg] Is there any way we could allow SVGs to link to other files? #10481

LeaVerou opened this issue Jun 21, 2024 · 18 comments
Labels

Comments

@LeaVerou
Copy link
Member

LeaVerou commented Jun 21, 2024

One of the biggest SVG pain points is around how locked down SVGs used in <img> or CSS background images are. My (potentially incorrect) understanding is that it was easier to do that at the time than properly investigate what the boundary is between addressing use cases while protecting end-users, and there was no interest from UAs to invest in that research. There was some activity recently around fixing longstanding SVG pain points, and potentially some renewed interest from UAs, so it may be an opportune point to revisit this.

Currently, SVGs used in <img> or CSS are severely crippled:

  • They cannot reference any web fonts, so any text is limited to system fonts. This harms accessibility as well, since authors have to resort to converting text to outlines, often with no textual fallback.
  • They cannot reference external stylesheets, so they have no access to the page’s design tokens (colors, fonts, etc.)
  • They cannot reference other SVGs via <use> so simple variations (e.g. a monochrome version of a logo or a + modifier on an icon) need to duplicate the entire graphic.

Could security folks explain the security risks involved so we could come up with a better solution than the current blanket ban on referencing (non-local) URLs? I’m really struggling to see what security risk importing a same-origin URL involves, especially when it’s one that’s already imported by the current document, but I’m not a security expert so I could be missing something.

Perhaps the issue is not around security but around loading behavior? If so, there are ways to address this (and if JS could do top-level await, we can certainly do this).

@LeaVerou LeaVerou added the SVG label Jun 21, 2024
@brandonmcconnell
Copy link

Related: #8634

@pygy
Copy link

pygy commented Jun 21, 2024

Beside B/W compat (authors may rely on the lack of 3rd party loading to get different behaviors in different contexts), I can't see why the iframe model couldn't be used for loading SVGs as <img>. Maybe this could be an opt-in behavior, via an attribute?

@svgeesus
Copy link
Contributor

  • They cannot reference any web fonts, so any text is limited to system fonts. This harms accessibility as well, since authors have to resort to converting text to outlines, often with no textual fallback.

  • They cannot reference external stylesheets, so they have no access to the page’s design tokens (colors, fonts, etc.)

This is why I always use <object> for SVG (except in the rare case where there is no text and no styling). But that brings in other problems.

@svgeesus
Copy link
Contributor

@LeaVerou
Copy link
Member Author

Beside B/W compat (authors may rely on the lack of 3rd party loading to get different behaviors in different contexts)

Is this a theoretical point or are you aware of such cases? Anyhow, we can do compat analysis to see if that’s the case.

I can't see why the iframe model couldn't be used for loading SVGs as <img>. Maybe this could be an opt-in behavior, via an attribute?

This does not work for using SVGs via CSS, and there are no attributes in that case. (presumably you mean <object>? <iframe> would not have intrinsic dimensions)

@zcorpan
Copy link
Member

zcorpan commented Jun 21, 2024

I believe it's a privacy issue. Consider a forum or blog that allows commenters to use <img src> (maybe only uploaded images). Before SVG in img was supported, this was fine, as the image formats browsers supported then could not "do" anything. But with SVG, if external resources are allowed, it can phone home, maybe when the image is scrolled into view.

@tabatkins
Copy link
Member

Yeah, SVG-as-img being locked down is indeed an important security consideration that can't be relaxed by default. It has to be some affirmative choice going forward, like an attribute or something that is added in the referencing markup.

@brandonmcconnell
Copy link

@tabatkins (cc @LeaVerou), I believe it could be beneficial to introduce a generic attribute to support both this behavior and that described in #8634, as well as any relevant features introduced in the future.

In #8634, I proposed an affirmative attribute as well. One potential solution could be an allow attribute, similar to the allow attribute used in iframes.

I don't mean to "muddy the waters" between these two issues, but using a generic attribute like allow might pave the way for future enhancements.

@BlackStar1991
Copy link

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 300"> <a href="https://hackyourmom.com/en/" target="_blank" rel="nofollow noopener"> <path d="M0 157v-14c.4-3.6.9-7.2 1.3-10.8C5.7 99.6 18.7 71 41.5 47.1 64 23.6 91.3 8.7 123.4 3c7.1-1.3 14.4-2 21.6-3h10c3.9.4 7.8.8 11.7 1.3 28.5 3.6 54.3 13.9 76.7 32 28.8 23.4 47 53.4 53.5 90.1 1.3 7.1 2 14.4 3 21.6v10c-.4 3.9-.8 7.8-1.3 11.8-3.6 28.5-13.8 54.3-32 76.7-23.2 28.6-52.8 46.6-89.1 53.5-6.8 1.3-13.7 2.1-20.6 3.1h-14c-1.3-.3-2.5-.8-3.8-.9-25.8-1.6-49.6-9.6-71-23.8C32.9 252 11 219.4 3 177.8c-1.3-7-2-13.9-3-20.8zm79.3-10.1c-1.8 10-.3 18 4.2 25.4 6.1 10 15.4 16.4 25.4 21.9 4.9 2.6 9.9 4.9 16 7.8-9.8 2.2-18.5 4.1-27.4 6.1-.6-2.6-.8-4.6-1.5-6.4-.5-1.4-1.9-3.7-2.5-3.5-2.5.5-4.8 1.8-7 2.9-.2.1.3 2.4.7 2.5 4.7.7 3.7 4.6 4.8 7.9-5 1-9.6 2.1-14.3 2.8-3.6.6-7 2.2-11-.1-2.8-1.7-5.7 1.3-5.3 4.8 1.1 9.9 1.9 10.3 10.2 5.6.1-.1.3-.2.5-.2 7.1-1.4 14.2-2.8 21.5-4.3.7 3.5 1.1 6.5 2.1 9.2.4 1 2.4 2.3 3.6 2.1 1.9-.3 3.7-1.6 5.5-2.4-1-1-2.1-2-3-3.1-.8-1.2-1.3-2.6-2.1-4.3 9.7-2.1 18.8-3.4 27.5-6.1 14.8-4.5 29.2-5.6 44.2-.4 9.2 3.2 19 4.4 30.2 6.8-2.2 2.1-3.3 3.4-4.6 4.3-2.3 1.5-2.5 3.1-.2 4.6 4.1 2.6 7.3 1.1 8.3-3.6.5-2.3 1.1-4.7 1.7-7.1 5 1.1 9.4 1.9 13.8 2.9 3.7.9 7.9.5 10.6 4.3.6.8 5 .4 5.1-.1.9-3.8 2.4-8 1.4-11.5-.9-3.2-4.6-1.9-7.2-.2-.4.2-1 .2-1.4.1-6.9-1.4-13.8-2.8-21.1-4.2 1.2-3.3 0-7.2 4.7-7.8.1 0 .4-3.3-.3-3.9-3.9-3.3-7.5-1.8-8.6 3.2-.3 1.6-.9 3.1-1.5 5.2-8.9-2-17.5-4-27.5-6.3 3.6-1.6 5.9-2.6 8.1-3.6 11-5.1 21.4-10.9 29.4-20.2 7.5-8.6 10.6-18.3 8.3-30.4-1.2 1.3-2 1.9-2.5 2.7-12.9 21.1-32.9 32.2-55.2 40.6-9 3.4-16.9 3.5-25.8 0-19.3-7.6-37.6-16.3-50.3-33.7-2.2-3-4.5-6.1-7.5-10.3zM95.2 112c1.1.2 1.9.4 2.7.5 10.2.9 12.1 3.1 12.3 13.5.1 5.3-.1 10.7.4 16 1.4 16.5 12.9 24.5 29.3 20.4v-10.7c-.9-.2-1.6-.5-2.2-.4-9.4.9-13.5-3.8-13.4-14.6.1-4.3-.1-8.7 0-13 .1-7.4-1.5-13.8-10-17 7.3-2.2 9.2-7.4 9.6-13.3.3-3.8.2-7.6.2-11.5 0-11.7 1.3-13 12.9-15.1 1.2-.2 2.9-2.3 2.8-3.4-.1-2.7-.5-7.1-1.9-7.6-9.8-3.7-23.5 3.3-26 13.5-1.4 5.7-1.6 11.8-1.7 17.8-.3 11.7-1.6 13.3-13 14-.6 0-1.2.3-2 .5V112zM160 66.3c1.5.2 2.7.4 4 .6 8.8.7 11.6 3.8 11.7 12.7 0 4 0 8 .1 12 .1 6.7 1.8 12.5 9.2 14.9-7.5 4.4-9.1 6.9-9.4 15.3-.2 6.3.1 12.7-.4 19-.6 7.5-3.4 9.8-10.8 10.3-1.4.1-2.9.3-4.3.4v11.4c2.2.1 4 .3 5.8.4 14.8.3 22.7-7 23.4-21.8.2-4.7.1-9.3.2-14 .1-11.7 2-13.8 13.5-15.1.3 0 .5-.3.9-.5v-10.7c-1.4-.1-2.4-.2-3.4-.2-7.7-.3-10.4-2.8-10.9-10.6-.3-4.6 0-9.3-.3-14-1-15.8-13.8-24.6-29.3-20.1v10z" style="fill:#f06"/> </a> </svg>

Maybe just limit the use of third-party, unsafe inserts in and then you won't have to worry about someone embedding unsafe code into the image?

@LeaVerou
Copy link
Member Author

@zcorpan If a static image is hotlinked, it can absolutely phone home, since it can be server-generated and the URL rewritten to look like a regular static image. Though I see your point: if SVGs could phone home, disallowing hotlinking would not be enough. But then it sounds like same-origin URLs should be fine?

@tabatkins What is insecure about SVGs being able to link to same origin URLs? We can introduce an opt-in mechanism for cross-origin requests.

@brandonmcconnell Whatever we come up with should work in CSS too, which is the biggest pain point (for HTML one can always use <object> worst case). An attribute doesn’t.

@BlackStar1991 Nobody is talking about clicking hyperlinks. I doubt that’s even possible with the current image rendering pipeline. This is about linking to resources like fonts, CSS files, or other SVGs.

@svgeesus
Copy link
Contributor

Before SVG in img was supported, this was fine, as the image formats browsers supported then could not "do" anything. But with SVG, if external resources are allowed, it can phone home, maybe when the image is scrolled into view.

That argues for a finer-grained access model. The current "make sure SVG is painful or inefficient" is not really helping.

@svgeesus
Copy link
Contributor

Nobody is talking about clicking hyperlinks. I doubt that’s even possible with the current image rendering pipeline.

It isn't. SVG in <img> or in CSS has no interactivity, no pointer events, so activating a hyperlink is not possible.

@ydaniv
Copy link
Contributor

ydaniv commented Jun 23, 2024

There are other use cases that this proposal still won't cater for, like referencing elements from that SVG, or manipulating with JS.
Ideally if we had something like a src attribute on <svg> to import content that would be nice.
But still won't solve the CSS use-case.

@Crissov

This comment was marked as off-topic.

@LeaVerou
Copy link
Member Author

There are other use cases that this proposal still won't cater for, like referencing elements from that SVG, or manipulating with JS. Ideally if we had something like a src attribute on <svg> to import content that would be nice. But still won't solve the CSS use-case.

Isn’t that what <use> is for? (which is part of this proposal)

@ydaniv
Copy link
Contributor

ydaniv commented Jun 24, 2024

Yes, but it's inserted into a shadow tree, so it's a bit limited. Maybe we could reuse this concept in a more modern fashion that could answer the <img> use-case as well?

@LeaVerou
Copy link
Member Author

@ydaniv Like how?

@ydaniv
Copy link
Contributor

ydaniv commented Jun 24, 2024

Well, ideally I'd like a way to have the same power of having an inline SVG, perhaps with opt-in/out of layers of encapsuation (from seamless inline, through <use> and to <img>) - e.g. as light/shadow DOM, but with the ability to load async via src and perhaps same performance customization like loading, fetchpriority, etc.
So not sure yet what's the best way forward:

  • New attributes on <img>?
  • New attributes on <svg>?
  • <object>?
  • A new <vector> element??

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

9 participants