-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Consider allowing document.domain = null
#2757
Comments
There might be a reasonable use case for nulling out `document.domain` in order to prevent a document from being able to access the DOM of other documents served from the same physical origin (by walking the frame tree of its embedder, for example). This patch implements `document.domain = null` behind the experimental flag in order to determine whether or not it solves the problem without unworkable side-effects. If so, I'll formalize whatwg/html#2757 into a real patch against HTML for discussion/ Bug: 733150 Change-Id: Ic6906d17b6e8bcb1882408ac6152ae3dd6f8700a Reviewed-on: https://chromium-review.googlesource.com/535536 Reviewed-by: Jochen Eisinger <jochen@chromium.org> Cr-Commit-Position: refs/heads/master@{#479363} WPT-Export-Revision: a37e7a6db46271f09f79ef6bbc4938274cb72a0e
I understand why allowing website to move themselves to a unique origin is useful to you. I also wonder what @bzbarsky and @annevk have to say about this. |
Moving pages into a unique origin is not what I'm suggesting; we can do that very well today with
I agree with the implication that we wouldn't have introduced
Yes. For the specific use cases I'm targeting, these aren't important, but I grant you that complete isolation would require significantly more work than the change proposed here. That's what @estark37 is working towards in https://wicg.github.io/isolation/. This change is significantly smaller than that one will end up being, and does not encompass nearly the same set of threats. It blocks DOM access between same-origin resources that want to distrust each other. That seems like a reasonable primitive to provide. |
OK, to clarify, you want to break same-originness with other webpages on the same origin but the origin should not really be unique? You want an origin that sort-of serializes to scheme://null:port which will be shared with...whom? You said this will be DOM only, so fetches from the page towards its (previous) origin are supposed to remain same-origin? The line we try to draw seems a bit fuzzy to me. I understand you want the linked same origin-domain check to fail and everything that does a same origin check to succeed? |
Here's a concrete case in which this would be helpful:
The nice thing about building on top of |
It doesn't sound like the proposal is to change anything about "same origin" checks, just "same origin-domain" ones, right? In particular, the serialization of the origin (which is not affected by document.domain right now) would not change in any way. This seems fairly simple to implement, fwiw. That said, the protection it would give you would be pretty limited. Looking at the use cases listed in #2757 (comment):
This part would in fact work. This is the strongest argument for doing this. That said, this is very much limited to takeovers of already-existing pages. The thing that did
All the navigation checks are for "same origin", not "same origin-domain", so not affected by this.
I'd really like to know whether there are other things we're trying to protect from here. Basically, implementation complexity is low, spec complexity is moderate (and given the trouble the spec has had with actually defining origins I'm very wary of adding complexity in that definition). Benefit seems pretty low to me so far, but I'm willing to be convinced that it's larger than it seems. It would just be unfortunate to add the complexity without gaining further security. And note that anything that allows a page to use a string to create another page that is same origin with it but not same origin-domain (i.e. acts like document.domain is not set) would effectively make the security benefit completely nonexistent. So we have the additional spec complexity of ensuring that nothing allows that, now or in the future. :( |
Although I think addressing @bzbarsky's questions about expounding on the benefit/cost ratio here are more important, I want to push on the stack my initial reaction, which is that it seems better to tie this to other features (sandboxing? feature policy?) instead of using document.domain. But let's leave that discussion until after we've agreed, or not, that this is a problem worth solving. |
Thanks for taking a look, @mozfreddyb, @bzbarsky, and @domenic.
I agree that this is a limitation. However, the ecosystem has developed a few (anti-?)patterns that fit this model pretty well. Consider (Put aside for the moment the question you're surely asking yourself about whether this is a sane mechanism. It's a widely used IAB standard, for good or for ill) So. "Sandbox!", you say, rightly. That can work in many scenarios, thanks to "Subdomains!", you say, also rightly. This would have some negative performance impact, as calculating the correct suborigin for a given ad takes some time, as does the fact that clients would move from a cache hit to an additional network request for each "new" We could do it via feature policy, I suppose (@cramforce suggested a particularly verbose option). That seems like more work for the ~same result, but it might be worth exploring. We're also looking at addressing these concerns through Suborigins, which is also more work for a result that might or might not actually be what folks want here. That's a long way of saying that we could design something more targeted, but
Hrm. You're right about the spec, which is unfortunate, because both Chrome and Safari block navigations if Perhaps we can agree on adopting that behavior? :)
I think we should have that complexity today; |
For the Edge behavior, they had no checks at all on navigation (which is actually what the spec says, btw!) as of when w3c/html#780 was filed. They were going to add some, but it wasn't clear to me exactly what. The lack of spec action on that part is pretty discouraging, by the way: we should really have it as a higher priority to fix security bugs in specs. I can test a link you give me in Edge if you want, but web-platform-tests/wpt#6243 doesn't seem to have any links to where a live test lives. :(
For a very restricted meaning of "talk to". And in general it does not prevent you from creating things you control which can talk to those documents (but can't talk to you). Or at least I cannot prove that it prevents that. That was never part of the threat model, because it was always assumed that you were hostile you would simply do whatever you wanted to those other documents before setting But for your new "take over" use case you want to be able to prove exactly that. |
There might be a reasonable use case for nulling out `document.domain` in order to prevent a document from being able to access the DOM of other documents served from the same physical origin (by walking the frame tree of its embedder, for example). This patch implements `document.domain = null` behind the experimental flag in order to determine whether or not it solves the problem without unworkable side-effects. If so, I'll formalize whatwg/html#2757 into a real patch against HTML for discussion/ Bug: 733150 Change-Id: Ic6906d17b6e8bcb1882408ac6152ae3dd6f8700a Reviewed-on: https://chromium-review.googlesource.com/535536 Commit-Queue: Mike West <mkwst@chromium.org> Reviewed-by: Jochen Eisinger <jochen@chromium.org> Cr-Commit-Position: refs/heads/master@{#479470}
Ah. I agree that this seems like something we should change. I'll comment on that bug.
Restricted in a way that seems to fit the contours of a class of problem, as I hope the use case above demonstrates. :)
I'd be interested in walking through the things you're concerned about. I haven't validated any of this against the spec, but my expectation is that anywhere we inherit the origin of a document, we ought to inherit the entire origin, including
I'd also note that the particular use case I'm thinking about would involve setting |
There might be a reasonable use case for nulling out `document.domain` in order to prevent a document from being able to access the DOM of other documents served from the same physical origin (by walking the frame tree of its embedder, for example). This patch implements `document.domain = null` behind the experimental flag in order to determine whether or not it solves the problem without unworkable side-effects. If so, I'll formalize whatwg/html#2757 into a real patch against HTML for discussion/ Bug: 733150 Change-Id: Ic6906d17b6e8bcb1882408ac6152ae3dd6f8700a Reviewed-on: https://chromium-review.googlesource.com/535536 Reviewed-by: Jochen Eisinger <jochen@chromium.org> Cr-Commit-Position: refs/heads/master@{#479363} WPT-Export-Revision: a37e7a6db46271f09f79ef6bbc4938274cb72a0e
I'm still not 100% convinced that the restrictions here are sufficient to actually close up all the gaps. And no, I don't have a specific attack scenario in mind so far; I just feel that the API surface involved is huge and I have seen no credible attempt to prove that the restrictions are enough. In particular, an analysis of all the places in platform that check "same origin" vs "same origin-domain" and why they are not problems here would seem like an important thing to do before we decide that we're offering safety guarantees.
That is my expectation too, but definitely not the case in the spec. And again, anaysis of all the cases that rely solely on "same origin" is needed.
OK. So the safety guarantees from this feature are pretty carefully tailored to this specific use case... One other thing (and this just occurred to me, sorry; shows you how easy it is to get tied up in implementation details and lose sight of the big picture). The spec and implementations have actively been removing cases that check for "same origin-domain" in favor of using "same origin" as much as possible, with an explicit goal of deprecating and eventually removing If we now start using |
I appreciate the feedback, and the time you've spend putting together responses. Thanks! Before diving back into the line-by-line, I'm waiting for feedback from the folks at Google that are interested in addressing the problem I spelled out above. If it turns out that this mechanism doesn't actually solve their problem, then we can save ourselves some back-and-forth. If it seems effective, then I hope you'll indulge a bit more discussion on the details. :) |
So I've been thinking about the original use case described in #2757 (comment) and I'm not sure why |
Closing this as since this was raised we've added various ways to mitigate the impact of |
Folks generally use
document.domain
to relax the same-origin policy, allowing multiple documents in the same eTLD+1 to reach into each other's DOM and muck around. It might be reasonable to use the same mechanism to harden the policy, disallowing access even when it would otherwise be granted.That is, something like
document.domain = null
could cause a document's origin to fail all "same origin-domain" checks that relied upon the domain check in step 2.1 of that algorithm.I'm prototyping this in https://chromium-review.googlesource.com/c/535536/ to let some folks on Google's ads team play around with it to see if they can harden some of DoubleClick's ad frames. It might also be useful for other projects that run un- or quasi-trusted user content on shared domains.
WDYT?
/cc @mozfreddyb @ckerschb @dveditz / @johnwilander / @travisleithead
The text was updated successfully, but these errors were encountered: