Intent to Ship: SVG foreignObject does not taint the canvas for blob URLs

130 views
Skip to first unread message

Chromestatus

unread,
Sep 18, 2024, 3:55:05 PMSep 18
to blin...@chromium.org, fs...@chromium.org, sche...@chromium.org

Contact emails

sche...@chromium.org

Explainer

None

Specification

https://html.spec.whatwg.org/multipage/canvas.html#security-with-canvas-elements

Summary

The ability to use an <img> element with an SVG source in a HTML canvas drawImage operation has long been supported by all browsers, but the canvas tainting behavior varies across platforms. All browsers taint the canvas when the SVG source includes a foreignObject tag and is referenced via a HTTP URI scheme. When the same SVG is referenced through a data URI all browsers agree not to taint the canvas. However, when a blob URI is used both Chromium (before this change) and WebKit taint the canvas, but Gecko does not. When this feature is shipped Chromium's behavior will match that of Gecko, allowing a wider range of SVG content to be used in canvas drawImage calls without tainting.



Blink component

Blink>Canvas

TAG review

None

TAG review status

Not applicable

Risks



Interoperability and Compatibility

The feature adds functionality and has no interop risk. We align with Gecko with this change, and begin to differ from WebKit.



Gecko: Shipped/Shipping

WebKit: No signal

Web developers: Strongly positive The bug has developers complaining about the lack of this feature. Stack Overflow also has questions about it.

Other signals:

WebView application risks

Does this intent deprecate or change behavior of existing APIs, such that it has potentially high risk for Android WebView-based applications?

No. The change makes HTML canvas image read-back slightly more permissive but otherwise has no impact.



Debuggability

None



Will this feature be supported on all six Blink platforms (Windows, Mac, Linux, ChromeOS, Android, and Android WebView)?

Yes

All platforms support the underlying functionality. We are changing the tainting behavior, not the underlying mechanisms.



Is this feature fully tested by web-platform-tests?

Yes

The CL that enables the feature will include comprehensive canvas tests. Existing tests cover the various privacy concerns, such as ensuring the SVG content is indeed non-interactive.



Flag name on chrome://flags

None

Finch feature name

None

Non-finch justification

The code change adjusts tainting behavior, which is a state flag on the HTML canvas context. Testing confirms that the existing behavior is maintained, and the new behavior allows more permissive behavior.



Requires code in //chrome?

False

Tracking bug

https://issues.chromium.org/issues/41054640

Measurement

No explicit plan though we could add UseCounters to see how often the change hits.

Availability expectation

Available in Chromium-based browsers and Gecko. No idea when it might be available in WebKit.

Adoption expectation

I expect sites to transition from Data-URI to Blob-URI for this use case. I would expect it to happen as sites update or look for performance improvements.

Adoption plan

No explicit plan.

Non-OSS dependencies

Does the feature depend on any code or APIs outside the Chromium open source repository and its open-source dependencies to function?

No.

Estimated milestones

Shipping on desktop 131
Shipping on Android 131
Shipping on WebView 131


Anticipated spec changes

Open questions about a feature may be a source of future web compat or interop issues. Please list open issues (e.g. links to known github issues in the project for the feature specification) whose resolution may introduce web compat/interop risk (e.g., changing to naming or structure of the API in a non-backward-compatible way).

No change.

Link to entry on the Chrome Platform Status

https://chromestatus.com/feature/5196074156032000?gate=5159222329999360

This intent message was generated by Chrome Platform Status.

Domenic Denicola

unread,
Sep 19, 2024, 12:16:06 AMSep 19
to Chromestatus, blin...@chromium.org, fs...@chromium.org, sche...@chromium.org, Dominic Farolino
Seems like a good idea!

On Thu, Sep 19, 2024 at 4:55 AM Chromestatus <ad...@cr-status.appspotmail.com> wrote:

Contact emails

sche...@chromium.org

Explainer

None

Specification

https://html.spec.whatwg.org/multipage/canvas.html#security-with-canvas-elements

I spent some time looking into the specification situation for this change, to understand how the interop problem might have arisen.

Unfortunately, the current spec is a bit of a mess. The only information on whether an <img> will taint the canvas is given by https://html.spec.whatwg.org/#the-image-argument-is-not-origin-clean , which says that it's tainted if "image's current request's image data is CORS-cross-origin". The definition of "image data" is not clear, but at least some parts of the spec assume that it is a response. A response is a generic fetch-level concept and doesn't have any SVG-specific notions, like foreignObjects.

I think at the very least we should open a spec issue about this. It would be helpful to explain how the tainting is implemented in Chromium (and maybe other browsers, if you have that info) so we can see where the mismatch is between spec and implementation.

It would also be ideal if we could add some sort of spec patch, even if it's a hack on top of unsteady foundations, to capture this behavior for everyone. One idea might be to add something near https://html.spec.whatwg.org/#updating-the-image-data:img-req-data-2 like

> If the resource obtained is an SVG image meeting [X conditions], then it must be considered as CORS-cross-origin, even if the fetch response was CORS-same-origin.

Does this sound reasonable to you? I don't want to throw up roadblocks on a small change that will improve developers' lives. But I think we can multiply our impact here by doing a bit more work to straighten out the ecosystem for everyone. And it might get some good discussion from WebKit as well.
 
--
You received this message because you are subscribed to the Google Groups "blink-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/blink-dev/66eb300e.2b0a0220.28f9c2.0061.GAE%40google.com.

Stephen Chenney

unread,
Sep 19, 2024, 9:48:25 PMSep 19
to Domenic Denicola, Chromestatus, blin...@chromium.org, fs...@chromium.org, Dominic Farolino
Reply to the spec concerns inline ...

On Thu, Sep 19, 2024 at 12:15 AM Domenic Denicola <dom...@chromium.org> wrote:
Seems like a good idea!

On Thu, Sep 19, 2024 at 4:55 AM Chromestatus <ad...@cr-status.appspotmail.com> wrote:

Contact emails

sche...@chromium.org

Explainer

None

Specification

https://html.spec.whatwg.org/multipage/canvas.html#security-with-canvas-elements

I spent some time looking into the specification situation for this change, to understand how the interop problem might have arisen.

Unfortunately, the current spec is a bit of a mess. The only information on whether an <img> will taint the canvas is given by https://html.spec.whatwg.org/#the-image-argument-is-not-origin-clean , which says that it's tainted if "image's current request's image data is CORS-cross-origin". The definition of "image data" is not clear, but at least some parts of the spec assume that it is a response. A response is a generic fetch-level concept and doesn't have any SVG-specific notions, like foreignObjects.

I think at the very least we should open a spec issue about this. It would be helpful to explain how the tainting is implemented in Chromium (and maybe other browsers, if you have that info) so we can see where the mismatch is between spec and implementation.

Yes, the spec on tainting is a mess and not very clear at all. I will happily create an issue and try to get the spec updated.

It would also be ideal if we could add some sort of spec patch, even if it's a hack on top of unsteady foundations, to capture this behavior for everyone. One idea might be to add something near https://html.spec.whatwg.org/#updating-the-image-data:img-req-data-2 like

> If the resource obtained is an SVG image meeting [X conditions], then it must be considered as CORS-cross-origin, even if the fetch response was CORS-same-origin.

Does this sound reasonable to you? I don't want to throw up roadblocks on a small change that will improve developers' lives. But I think we can multiply our impact here by doing a bit more work to straighten out the ecosystem for everyone. And it might get some good discussion from WebKit as well.

I agree that we can be explicit about what makes an SVG image same vs. cross origin. It's basically recursive in that an SVG is same origin if it only references same-origin image content, and then we have the special foreignObject rules where a foreignObject is same-origin if the SVG is referenced via a data URI (and blob when this intent ships) but not when referred to by a URL. Part of the confusion arises because it's the SVG spec that talks about SVG in a non-interactive context which basically means "when used in an img tag".

It may be that we need to also update the information at the "updating-the-image-data-img-req-2" link above, because it says nothing about what to do when the <img> src is not a regular URL, but is instead a data URI or blob. It may be covered someplace, but I couldn't find it while researching this email.

Vladimir Levin

unread,
Oct 1, 2024, 3:10:49 PM (3 days ago) Oct 1
to Stephen Chenney, Domenic Denicola, Chromestatus, blin...@chromium.org, fs...@chromium.org, Dominic Farolino
This changes the tainting and does not add functionality, right? Or is this adding a new ability?
 


Gecko: Shipped/Shipping

WebKit: No signal

It's worthwhile to file a WebKit position here since we will start to deviate from that behavior.
 


Web developers: Strongly positive The bug has developers complaining about the lack of this feature. Stack Overflow also has questions about it.

 
Reply all
Reply to author
Forward
0 new messages