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

Adapt "funky elements handling" to include SVG. #212

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

otherdaniel
Copy link
Collaborator

@otherdaniel otherdaniel commented Mar 28, 2024

  • Add SVG & to list of javascript:-attributes.
  • Add a list for SVG animations.
  • Minor edits when using those lists.

Preview | Diff

Copy link
Collaborator

@annevk annevk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cure53 do you know why DOMPurify bans all SVG animation? Do you know other maintainers we can reach out to?

index.bs Outdated
1. If the [=animating URL attributes list=] [=SanitizerConfig/contains=]
«[|elementName|, |attrName|]» and |attr|'s
[=get an attribute value|value=] [=string/is=] "`href`" or
"`xlink:href`":
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should double check that xlink:href is actually meaningful as it supposedly only works when xmlns puts xlink in scope which is never the case in HTML.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

xlink:href works in HTML regardless of namespace declarations. https://html.spec.whatwg.org/multipage/parsing.html#adjust-foreign-attributes

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zcorpan that is xlink:href as an attribute, but not as an attribute value of these SVG attributes.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I see. Still, xmlns:xlink is also an adjusted attribute.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, so it should work when xmlns:xlink is also specified. In which case we want to always ban xlink:href as is suggested here. (Having tests for all these combinations would be good though.)

I guess the other piece of feedback I forgot to note down here is that we should make sure we have the same processing model as these attributes have today, which regards to splitting on whitespace and such.

@securityMB
Copy link

@cure53 do you know why DOMPurify bans all SVG animation? Do you know other maintainers we can reach out to?

I believe the reason is that you can use SVG animation to animate href attribute which can lead to XSS.

For example:

<svg>
<animate xlink:href=#x 
         attributeName=href 
         values=javascript:alert(1) />
<a id=x>
  <text x=10 y=10>
    Click me
  </text>
</a>

@annevk
Copy link
Collaborator

annevk commented Apr 3, 2024

@securityMB thanks for weighing in! This PR attempts to tackle that in a more specific way, allowing generic animation features to continue to work. We are wondering if that is good enough or if we'll run into other trouble.

@lukewarlow
Copy link
Contributor

Trusted types covers the SVGAnimatedString IDL type, which covers you updating an SVGScriptElement hrefs baseVal, and it also includes the javascript: url pre-navigation handling for when a javascript URL is defined in markup and navigated to.

So I think if sanitizer is stripping the javascript: value for href (and probably it's xlink variant?) from any markup via the safe sync, along with probably stripping out the script element from SVG entirely (aka follow the same model as happens with HTML), that should be sufficient?

@annevk
Copy link
Collaborator

annevk commented Apr 3, 2024

@lukewarlow no, see the example above: #212 (comment). We cannot rely on the navigation check Trusted Types has here. We need something along the lines of this PR or ban SVG animation entirely, but that seems less well founded.

@lukewarlow
Copy link
Contributor

Sorry to clarify I didn't mean to rely on TT for anything I was just providing context on what TT does for this area.

@otherdaniel
Copy link
Collaborator Author

otherdaniel commented Apr 8, 2024

I wrote a test to figure out what browsers will actually do...

  • Animating "href" to a javascript:-url is implemented by all browsers.
  • Chrome & Safari, but not Firefox, will animate "xlink:href", but only if there's an explicit xmlns:xlink declaration.
  • There seems to be no pre-processing (like strippping whitespace) involved. I couldn't get " href " to animate.

(Source is here and there.)


[Edit: In HTML documents, Chrome & Safari will animate "xlink:href", but only if there's an explicit xmlns:xlink declaration. They will not animate another prefix, even with a declaration. In XML documents, both will animate whatever prefix has the proper xmlns: declaration, e.g. bla:href with an xmlns:bla=.... It seems FF will not animate any name with any namespace prefix in any document mode.]

@otherdaniel
Copy link
Collaborator Author

The current version now does this:

  • Remove the following attributes, if their value has a `javascript:' prefix:
    • <a href>
    • <area href>
    • <form action>
    • <input formaction>
    • <button formaction>
    • <a href> (SVG namespace)
    • <a xlink:href> (SVG namespace)
    • href in any element in the MathML namespace
  • Remove attributeName attribute, if its value is href or xlink:href from:
    • <animate attributeName> (SVG namespace; also all below)
    • <animateMotion attributeName> (as above)
    • <animateTransform attributeName> (as above)
    • <set attributeName> (as above)

I think this covers all cases we have discovered.

Presently, this just non-chalantly states the algorithm. Should I add a note and/or appendix that explains how we got there, in case someone else wants to understand what the point is?

index.bs Outdated Show resolved Hide resolved
index.bs Outdated

</div>

<div class=note>
<span class=marker>Note:</span> Current browsers support `javascript` URLs
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would make this javascript: URLs throughout (including the :), including in definitions. I think that's more consistent with how we approach this elsewhere.

index.bs Show resolved Hide resolved
Copy link
Collaborator

@annevk annevk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this looks good now, modulo nits. It's unfortunate we have to invoke the URL parser though, but I guess so be it. We never said that safe was going to be cheap.

index.bs Outdated Show resolved Hide resolved
index.bs Outdated Show resolved Hide resolved
index.bs Outdated Show resolved Hide resolved
- Add SVG <a href> & <a xlink:href> to list of javascript:-attributes.
- Add a list for SVG animations.
- Minor edits when using those lists.
- Check basic URL parser for failure.
- Use colon to designate javascript: scheme.
@otherdaniel
Copy link
Collaborator Author

In the meeting, we had briefly discussed what the support for MathML + href + javascript: was. It seems there's already WPT tests for this: https://wpt.fyi/results/mathml/relations/html5-tree?label=master&label=experimental&aligned&q=mathml%2Frelations%2Fhtml5-tree%2Fhref-click

href-click-003.tentative.html tests navigating to a javascript:-url.

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

Successfully merging this pull request may close these issues.

6 participants