w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.46k stars 657 forks source link

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

Open LeaVerou opened 3 months ago

LeaVerou commented 3 months ago

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:

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).

brandonmcconnell commented 3 months ago

Related: https://github.com/w3c/csswg-drafts/issues/8634

pygy commented 3 months ago

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 commented 3 months ago
  • 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 commented 3 months ago

Related:

LeaVerou commented 3 months ago

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 commented 3 months ago

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 commented 3 months ago

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 commented 3 months ago

@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 commented 3 months ago

`

`

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 commented 3 months ago

@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 commented 3 months ago

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 commented 3 months ago

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 commented 3 months ago

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 commented 3 months ago

Really off topic here, but now I wonder whether usemap (without a reference to a <map>) should change that behavior.

<img src="interactive.svg" usemap>

… and whether omitted alt and title attributes should be automatically populated by the resource’s <desc> and <title> elements.

LeaVerou commented 3 months ago

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 commented 3 months ago

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 commented 3 months ago

@ydaniv Like how?

ydaniv commented 3 months ago

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: