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

Put safeguards around attribute nodes #47

Closed
mikesamuel opened this issue Jun 3, 2018 · 9 comments
Closed

Put safeguards around attribute nodes #47

mikesamuel opened this issue Jun 3, 2018 · 9 comments
Milestone

Comments

@mikesamuel
Copy link
Collaborator

There are two cases where moving a node from one parent to another might be problematic.

const div = document.createElement('div')
div.appendChild(document.createTextNode('alert(1)'));
const script = document.createElement('script')
while (div.firstChild) {
  script.appendChild(div.firstChild);
}

We need to be suspicious of append to <script> elements regardless, but there's also a problem with attributes.

const div = document.createElement('div');
const a = document.createElement('a');

div.setAttribute('href', 'javascript:alert(1)');
const attr = div.getAttributeNode('href');
div.removeAttributeNode(attr);

a.setAttributeNode(attr);

But what about when a node comes from one context to a similar context?

const a0 = document.createElement('a');
const a1 = document.createElement('a');

a0.setAttribute('href', policy.createURL('http://example.com'));
const attr = a0.getAttributeNode('href');
a0.removeAttributeNode(attr);

a1.setAttributeNode(attr);

Should we support this kind of transparent DOM restructuring?

@koto
Copy link
Member

koto commented Jun 3, 2018

Perhaps we can simply disable the offending functions? At least the ones related to attribute nodes seem to be on the way to being deprecated in DOM4.

@mikesamuel
Copy link
Collaborator Author

mikesamuel commented Jun 4, 2018

Disabling setAttributeNode would work.

myElement.attributes also exposes Attrs so we might need to guard the Attr.value setter regardless.

aElement.attributes.href.value = ...

aElement.getAttributeNode('href').value = ...

@koto
Copy link
Member

koto commented May 3, 2019

The text node in scripts vector should be covered in #133 (https://chromium-review.googlesource.com/c/chromium/src/+/1547746)

Regarding attribute node deprecation, this is probably not happening soon in practice: https://github.com/search?l=JavaScript&q=setAttributeNode&type=Code. Assuming they are here to stay, and are used it sounds like we need to guard them.

It seems like the attribute nodes are immutable, apart from their value (in specific, changing the name, localName or namespaceURI doesn't have any effect). Given that, we could be able to secure this by:

  • requiring the type at document.createAttribute(NS) and at Attr.value setter, assuming that for HTML namespace src attribute requires TrustedURL.
  • disallowing setAttributeNode on script elements, totally, or if attribute node name is src (as the type for script.src is different).

A more elegant fix would be to require TrustedURL|TrustedScriptURL on src nodes, tracking which type was used, and checking that with the element contract on setAttributeNode.

cc @otherdaniel

@koto
Copy link
Member

koto commented Jul 17, 2019

Closing this, see #50 (comment) for rationale (for cross-realm nodes). As for the script node text manipulation via child nodes, we addressed this in #133.

@koto koto closed this as completed Jul 17, 2019
@koto koto reopened this Aug 12, 2019
@koto
Copy link
Member

koto commented Aug 12, 2019

Reopening for attribute nodes. We should

  • Forbid setAttributeNode (or route their value through default policy like for script texts) on content attributes that are reflected by one of covered attributes, e.g.
    • iframe.srcdoc
    • script.src
  • Same for attribute node value setters.

@koto koto changed the title Cross context node copies Put safeguards around attribute nodes Aug 12, 2019
@koto koto added this to the v1 milestone Oct 10, 2019
@koto
Copy link
Member

koto commented Oct 21, 2019

A possible solution outlined in whatwg/dom#789 (comment)

chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Nov 13, 2019
…checks.

Element::setAttribute will perform trusted types checks, which (currently)
can be circumvented by obtaining the DOM's attribute node and setting the
value directly. This fixes this bypass, by performing identical checks when
the attribute node values are set, and/or the attribute node is attached to
an element.

Bug: 1008012
Bug: w3c/trusted-types#47
Change-Id: I1d8ead85b3fa11821c329e1f4af60c1e85ea8298
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Nov 13, 2019
…checks.

Element::setAttribute will perform trusted types checks, which (currently)
can be circumvented by obtaining the DOM's attribute node and setting the
value directly. This fixes this bypass, by performing identical checks when
the attribute node values are set, and/or the attribute node is attached to
an element.

Bug: 1008012
Bug: w3c/trusted-types#47
Change-Id: I1d8ead85b3fa11821c329e1f4af60c1e85ea8298
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Nov 14, 2019
…checks.

Element::setAttribute will perform trusted types checks, which (currently)
can be circumvented by obtaining the DOM's attribute node and setting the
value directly. This fixes this bypass, by performing identical checks when
the attribute node values are set, and/or the attribute node is attached to
an element.

Bug: 1008012
Bug: w3c/trusted-types#47
Change-Id: I1d8ead85b3fa11821c329e1f4af60c1e85ea8298
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Nov 18, 2019
…checks.

Element::setAttribute will perform trusted types checks, which (currently)
can be circumvented by obtaining the DOM's attribute node and setting the
value directly. This fixes this bypass, by performing identical checks when
the attribute node values are set, and/or the attribute node is attached to
an element.

Bug: 1008012
Bug: w3c/trusted-types#47
Change-Id: I1d8ead85b3fa11821c329e1f4af60c1e85ea8298
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1911215
Commit-Queue: Daniel Vogelheim <vogelheim@chromium.org>
Reviewed-by: Mike West <mkwst@chromium.org>
Cr-Commit-Position: refs/heads/master@{#716193}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Nov 18, 2019
…checks.

Element::setAttribute will perform trusted types checks, which (currently)
can be circumvented by obtaining the DOM's attribute node and setting the
value directly. This fixes this bypass, by performing identical checks when
the attribute node values are set, and/or the attribute node is attached to
an element.

Bug: 1008012
Bug: w3c/trusted-types#47
Change-Id: I1d8ead85b3fa11821c329e1f4af60c1e85ea8298
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1911215
Commit-Queue: Daniel Vogelheim <vogelheim@chromium.org>
Reviewed-by: Mike West <mkwst@chromium.org>
Cr-Commit-Position: refs/heads/master@{#716193}
moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this issue Nov 29, 2019
…ipulation with Trusted Types checks., a=testonly

Automatic update from web-platform-tests
[Trusted Types] Cover attribute node manipulation with Trusted Types checks.

Element::setAttribute will perform trusted types checks, which (currently)
can be circumvented by obtaining the DOM's attribute node and setting the
value directly. This fixes this bypass, by performing identical checks when
the attribute node values are set, and/or the attribute node is attached to
an element.

Bug: 1008012
Bug: w3c/trusted-types#47
Change-Id: I1d8ead85b3fa11821c329e1f4af60c1e85ea8298
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1911215
Commit-Queue: Daniel Vogelheim <vogelheim@chromium.org>
Reviewed-by: Mike West <mkwst@chromium.org>
Cr-Commit-Position: refs/heads/master@{#716193}

--

wpt-commits: 36362f1a77faf18831c8b596e7b5bee081629817
wpt-pr: 20228
xeonchen pushed a commit to xeonchen/gecko that referenced this issue Nov 29, 2019
…ipulation with Trusted Types checks., a=testonly

Automatic update from web-platform-tests
[Trusted Types] Cover attribute node manipulation with Trusted Types checks.

Element::setAttribute will perform trusted types checks, which (currently)
can be circumvented by obtaining the DOM's attribute node and setting the
value directly. This fixes this bypass, by performing identical checks when
the attribute node values are set, and/or the attribute node is attached to
an element.

Bug: 1008012
Bug: w3c/trusted-types#47
Change-Id: I1d8ead85b3fa11821c329e1f4af60c1e85ea8298
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1911215
Commit-Queue: Daniel Vogelheim <vogelheim@chromium.org>
Reviewed-by: Mike West <mkwst@chromium.org>
Cr-Commit-Position: refs/heads/master@{#716193}

--

wpt-commits: 36362f1a77faf18831c8b596e7b5bee081629817
wpt-pr: 20228
gecko-dev-updater pushed a commit to marco-c/gecko-dev-comments-removed that referenced this issue Nov 30, 2019
…ipulation with Trusted Types checks., a=testonly

Automatic update from web-platform-tests
[Trusted Types] Cover attribute node manipulation with Trusted Types checks.

Element::setAttribute will perform trusted types checks, which (currently)
can be circumvented by obtaining the DOM's attribute node and setting the
value directly. This fixes this bypass, by performing identical checks when
the attribute node values are set, and/or the attribute node is attached to
an element.

Bug: 1008012
Bug: w3c/trusted-types#47
Change-Id: I1d8ead85b3fa11821c329e1f4af60c1e85ea8298
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1911215
Commit-Queue: Daniel Vogelheim <vogelheimchromium.org>
Reviewed-by: Mike West <mkwstchromium.org>
Cr-Commit-Position: refs/heads/master{#716193}

--

wpt-commits: 36362f1a77faf18831c8b596e7b5bee081629817
wpt-pr: 20228

UltraBlame original commit: 5765ef6d9f1a1d561d37a365cda5c2084245145f
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified-and-comments-removed that referenced this issue Nov 30, 2019
…ipulation with Trusted Types checks., a=testonly

Automatic update from web-platform-tests
[Trusted Types] Cover attribute node manipulation with Trusted Types checks.

Element::setAttribute will perform trusted types checks, which (currently)
can be circumvented by obtaining the DOM's attribute node and setting the
value directly. This fixes this bypass, by performing identical checks when
the attribute node values are set, and/or the attribute node is attached to
an element.

Bug: 1008012
Bug: w3c/trusted-types#47
Change-Id: I1d8ead85b3fa11821c329e1f4af60c1e85ea8298
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1911215
Commit-Queue: Daniel Vogelheim <vogelheimchromium.org>
Reviewed-by: Mike West <mkwstchromium.org>
Cr-Commit-Position: refs/heads/master{#716193}

--

wpt-commits: 36362f1a77faf18831c8b596e7b5bee081629817
wpt-pr: 20228

UltraBlame original commit: 5765ef6d9f1a1d561d37a365cda5c2084245145f
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified that referenced this issue Nov 30, 2019
…ipulation with Trusted Types checks., a=testonly

Automatic update from web-platform-tests
[Trusted Types] Cover attribute node manipulation with Trusted Types checks.

Element::setAttribute will perform trusted types checks, which (currently)
can be circumvented by obtaining the DOM's attribute node and setting the
value directly. This fixes this bypass, by performing identical checks when
the attribute node values are set, and/or the attribute node is attached to
an element.

Bug: 1008012
Bug: w3c/trusted-types#47
Change-Id: I1d8ead85b3fa11821c329e1f4af60c1e85ea8298
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1911215
Commit-Queue: Daniel Vogelheim <vogelheimchromium.org>
Reviewed-by: Mike West <mkwstchromium.org>
Cr-Commit-Position: refs/heads/master{#716193}

--

wpt-commits: 36362f1a77faf18831c8b596e7b5bee081629817
wpt-pr: 20228

UltraBlame original commit: 5765ef6d9f1a1d561d37a365cda5c2084245145f
@koto
Copy link
Member

koto commented Mar 2, 2020

Closing this, the followup is in whatwg/dom#809.

@koto koto closed this as completed Mar 2, 2020
@bathos
Copy link

bathos commented Apr 21, 2021

If I understand right this was resolved without disabling setAttributeNode, right?

I’m looking to confirm because currently setAttributeNode is (afaik) the only way to set attributes with names that don’t pass the “Name production in XML”* step in setAttribute/setAttributeNS.

* Or rather the unspecified(?) variant of that grammar which browsers really implement in practice. For example, 💩 is a valid HTML attribute name and a valid XML name, but all browsers today seem to think it’s not the latter).

@koto
Copy link
Member

koto commented Apr 21, 2021

The value of the node goes through a default policy, if the elem it's attaching to + attribute name matches what needs Trusted Types. If there's no default policy (or the value is rejected by it), setAttributeNode will throw:

http://gadgets.kotowicz.net/poc/tt/attributenode.html

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

3 participants