-
Notifications
You must be signed in to change notification settings - Fork 74
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
Putting guards at primitives instead of sinks #176
Comments
That's a really good idea! It's mostly just an exercise in finding the right primitives matching the current sinks. For example, for now Two potential downsides I see is that a) it might make the integration with other spec more verbose, so more challenging and b) maybe not everything is polyfillable. I'll take a look at where we could hook the current TT sink setters, and whether that causes some change of behavior (it will for individual |
One problem with the Fetch integration is that this would happen too late. To avoid having to taint track nodes, TT are guarded at node attribute setters, even if the node is not connected to the document. For example, for scripts fetch would only be triggered when the script is prepared, but we'd rather require the type earlier, in this case when setting the We could definitely benefit from Fetch integration e.g. by referring to (script-like Request destination)[https://fetch.spec.whatwg.org/#request-destination-script-like] and requiring the URL attributes being |
You can certainly put requirements on entry points. The main thing about having the actual guard at the primitive is to avoid missing entry points. Not sure about the note thing, "audioworklet" not being defined in a normative matter is a bug. |
That's fine, I was just trying to figure out where the Request destinations are defined and I still see some difficulty for speccing this, but it's likely I just misunderstood what you mean. Do you mean to add additional guards in e.g. fetch (the most likely algorithm that would relate to URL TTs), such that it rejects non-compliant values? E.g. If request initiator is "non-parser-inserted" , and request window's documents' TrustedTypeConfiguration's string at sink disposition is "reject" and a request URL is not a getTypeForDestination(request destination), reject with some error. That would require preserving the type of the URL in Fetch as well. So far we're not doing this yet in the JS fetch() call, because we looked into non-script URLs mostly to address a problem with If we'd want to keep JS fetch(string) to work regardless of TT enforcement, we need a way to track the requests initiated by DOM / other sinks from ones using XHR / Fetch - should we use initiator for that? |
Yeah, worklets are not defined well and have quite a few open issues against them... Perhaps you can ping some colleagues? Initiator might be useful if there's nothing else that gives it away. Note also that at a specification level URL is not a string, e.g., to make blob URLs work. So there's infrastructure already to attach additional data to URLs. |
I was able to tackle the javascript: URLs in a more developer-friendly matter. Previously, all navigational sinks required a TrustedURL. The only issue with those sinks was that they could potentially navigate to https://github.com/WICG/trusted-types/pull/204/files This places the burden on the authors who still use javascript: URLs, and makes sure that, in "TT mode" the javascript: URLs don't work by default. |
existing algorithms.
@annevk I've found a couple of algorithms that form the set of primitives that are a good target for guards. The issue is that as these primitives accept strings, or byte streams and are called a few levels deeper than the TT logic, and I don't know how to express in the spec that these should take TT into account, without clumsily passing an additional argumentall the way through the stack. I see something similar when HTML fragment parsing algorithms is called out as a special case e.g. here Would something like the following work for TrustedHTML for example? If this is acceptable, I can extend that approach to other types and primitive algos. |
…ascript: URLs. (#204) This removes the burden from all authors to create types when interacting with common sinks that usually don't cause DOM XSS (unless for javascript: URLs). This PR prevents javascript: URLs from working by default, and allows programmatic opt-in to enable them one-by-one for the few applications that need them. Related to #176. Partially addresses #169. Fixes #64.
There's three generic approaches we could take to implement checks at the primitive algorithms:
I've identified the following algorithms that would be affected. It seems that, after fixing #47, the TT behavior for the currently exposed APIs would be the same with and without the hardening fixes outlined below. HTML parsing
Attributes
Scripts
|
Moved some of this upstream to whatwg/html#3052 and whatwg/dom#789. |
I just want to write up a concrete analysis of what I think the spec text would look like for the approaches @koto mentions.
Other shared subtleties:
|
(DOM|USV)String. This is to hook up the Trusted Types validation during the ES->IDL type conversion to avoid funky issues with its default policy. See w3c/trusted-types#248, w3c/trusted-types#176
The 'putting guards at primitives' approach has surfaced issues with the default policy (#248). It looks like it's preferable to address the TT checks, with the default policy application at IDL conversion time (in one of the few variants outlined in whatwg/webidl#841) - so even "before" sinks. The advantages we get for avoiding the default policy problems seem to outweigh the complexity of guarding at all affected primitives. There are exceptions to that, more in line with the "at primitives" approach:
Please let us know if that sounds like a bad call, @annevk. |
(DOM|USV)String. This is to hook up the Trusted Types validation during the ES->IDL type conversion to avoid funky issues with its default policy. See w3c/trusted-types#248, w3c/trusted-types#176
(DOM|USV)String. This is to hook up the Trusted Types validation during the ES->IDL type conversion to avoid funky issues with its default policy. See w3c/trusted-types#248, w3c/trusted-types#176
I discussed this briefly with @koto and thought I'd file it to not lose track of the idea. What if instead of sinks we add the guards at the various primitives. E.g., not
<a>
,<form>
, etc. but "navigate". Notfetch()
,<img>
, etc. but "fetch". NotappendChild()
et al but "prepare a script" (or some such). NotinnerHTML
and friends but "HTML fragment parsing algorithm".This would put the actual protections right at the dangerous points. We'd still have to change sinks to allow for typed objects to reach the dangerous points, but there's no longer the issue of overlooking a sink or overlooking trusted types when adding a new sink. Or the issue of it not being clear how to update all the various sinks as with
Location
as we could opt not to add trusted types for all of them.The text was updated successfully, but these errors were encountered: