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

Figure out what to do with cross-document interactions #50

Closed
koto opened this issue Jun 5, 2018 · 6 comments
Closed

Figure out what to do with cross-document interactions #50

koto opened this issue Jun 5, 2018 · 6 comments
Labels
Milestone

Comments

@koto
Copy link
Member

koto commented Jun 5, 2018

(This is somewhat related to #47 and #49)

There are certain ways to obtain a reference to a different Document objects in the platform. For example:

Coincidentally, some of these methods are used by HTML sanitizers (e.g. https://github.com/cure53/DOMPurify), as it's the most convenient way of sanitizing client side.

If documents created by above methods are not restricted by the policies of the current document, it's possible to use string-based DOM API (potentially putting untrusted data) there, later on attaching the produced DOM nodes to the main document, effectively bypassing the restrictions of the policies.

It's possible to address that in several ways:

  • acknowledge, but don't prevent it. Policies are per-document, document creation functions are relatively rare and should be subject to a security review by other means than TT enforcement.
  • make the policies propagate to newly created synthetic document. CSP propagation rules state that CSP will propagate to <iframe srcdoc> and about:blank documents roughly, and it makes sense to tie it to those rules. Propagating the policies to other type of documents (e.g. same-origin <iframe src=/>) is obviously not a good idea.
  • guard document creation APIs: make the methods like createHTMLDocument throw on document creation if TTs are enabled. Expose the original implementation of the document producers within the policy (such that, e.g. a sanitizing policy could pass the document-creating function, or even a new document instance to a sanitizer lib). This might be hard to polyfill for all cases, especially XHR, and has a potential to break applications in additional ways, but making a sanitizer policy call CustomSanitizer(dirtyString, dirtyDocument) does sound like an elegant API to have, and would simplify existing sanitizer's code.
@koto
Copy link
Member Author

koto commented Jun 11, 2018

Another option @mikewest suggested is treating the policy per-realm, not per-document - so any interactions with a document (even if it's an inert one) are guarded by the existing policy.

@koto koto added the spec label Jun 13, 2018
@koto
Copy link
Member Author

koto commented Jun 14, 2018

To document the current behavior of the polyfill, createHTMLDocument respects the policies, while XMLHttpRequest and DOMParser documents don't, DOMParser being trivial to patch (Just make sure parseFromString needs a TrustedHTML:

http://jsbin.com/pogucemoni/edit?html,output

@koto
Copy link
Member Author

koto commented Jun 15, 2018

I added the DOMParser patch in #55.

@koto
Copy link
Member Author

koto commented Jan 18, 2019

For now, the polices are per-document.

@koto koto closed this as completed Jan 18, 2019
@koto koto reopened this Jun 1, 2019
@koto
Copy link
Member Author

koto commented Jun 1, 2019

This needs to be specified. If we apply CSP logic from https://www.w3.org/TR/CSP3/#initialize-document-csp, restrictions from the main document should be applied to local scheme documents (like about:blank, or iframe.srcdoc documents).

Current behavior in Chrome is that the CSP list is indeed propagated, but that only specifies the allowed policy names. The policies themselves need to be created again in the new document.

Additionally, it's possible to use policies created in another (same-origin) document to manipulate the contents of another document.
So for example 'about:blank' window may create a (more lax) policy and apply changes to its opener/parent. I'm not sure this is necessarily bad, as that window already has capabilities to do anything anyway. It might actually be a good thing, and allow for design where the parent window must still use policies when manipulating the child window. But we should most likely lock down the reverse.

Perhaps we should, when initializing a new document CSP list just lock down the policy names that were already created, such that at least the child window cannot piggyback on the name, and could only possibly create policies that were not yet claimed in the main window. This of course does not help if Trusted-Types: * is used.

@koto
Copy link
Member Author

koto commented Jul 17, 2019

It looks like we're addressing this with setting the restrictions for the realm (not for the document) - see #191.

This is not a complete solution, as cross-realm node import / adoption is possible (and would not be "caught" by TT), so one can create nodes in an unrestricted environment, and them import them back into the restricted realm. This, however, is not really within the TT threat model (protecting against a malicious developer).

Since those "colluding" realms have a direct ability to script each other, it seems pointless to introduce restrictions for DOM XSS injection sinks only via TT.

The proper solution for such vectors should rather be

  • to block the ability of creating understricted realms ; which authors can address via e.g. Origin Policy, and/or:
  • to block the ability for such realms to reference each other; which authors can address via the new COOP / COEP headers.

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

1 participant