Open Bug 1085214 Opened 10 years ago Updated 2 months ago

Implement Location.ancestorOrigins

Categories

(Core :: DOM: Window and Location, enhancement, P3)

enhancement

Tracking

()

Webcompat Priority P3

People

(Reporter: erik, Unassigned)

References

(Blocks 1 open bug, )

Details

(Keywords: dev-doc-needed, webcompat:platform-bug)

Attachments

(2 files)

User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:33.0) Gecko/20100101 Firefox/33.0
Build ID: 20141011015303

Steps to reproduce:

This is a request to implement location.ancestorOrigins like in webkit: https://bugs.webkit.org/show_bug.cgi?id=83493

The number of changes required in webkit were quite small; https://bug-83493-attachments.webkit.org/attachment.cgi?id=136361

This feature is very useful to check which parent domains you are running in and acting on this information.



Expected results:

location.ancestorOrigins should contain a read-only array of hostnames for all the parent frames.
There's no specification for this yet. It's being tracked at https://www.w3.org/Bugs/Public/show_bug.cgi?id=22699.
This is pretty easy to implement if we want to.  The question is whether we want to.  It leaks cross-site information that we may not really want to leak.
Yes, I think we should do this. It seems more important, from a security point of view, to me to enable content to ensure that they are only embedded by those that it expects to be embedded by, than it is to enable content to embed others "anonymously".

But of course this requires a security review.
Flags: sec-review?
Flags: sec-review? → sec-review?(dveditz)
Pages can already "ensure it's only embedded by those it expects" using CSP or postMessage. Adding an API with confusing privacy implementations doesn't seem necessary to me. I might be okay with this if it were opt-in for each ancestor.
Such an API could alert a website if they are being iframed by a site they do not expect to be iframed by.  Perhaps they haven't implemented CSP and don't have whitelist of frame-ancestors they should include in the header.  location.ancestorOrigins could help them compile that.

I feel like I'm missing the privacy concern with doing this.  I see that we are leaking information about what websites frame content, but we aren't leaking information about the user.

Needinfo'ing Dan because I'm not sure he's looking at the sec-review queue.
Flags: needinfo?(dveditz)
What is possible with ancestorOrigins is not possible with CSP or postMessage. Also there is nothing confusing about it, it just gives you the domain of every parent all the way up to the origin. It's only the hostname so I don't see how this leaks any privacy related information.

If someone could give me some hints at where to look I could take a shot at implementing this.
There is quite a difference between "Only allow framing from x,y,z" (CSP) and "tell me where else this user goes" (this). There is no other case where we allow a web page to read non-same-origin location data.

What can you do with ancestorOrigins that you can't do with CSP's whitelist approach other than blacklist specific parents? You know how security guys feel about blacklists vs whitelists.

Do you have any example pages that show this feature being used to good effect? Presumably you have examples if you think we need it. According to the webkit bug one use is to work around other non-standard webkit behavior (bug) that wouldn't be an issue in Firefox.

Making more information of this type available is going in the opposite direction of where we're heading with features to control the sending of referrers. Not quite the same, but does make me wonder if we'll then end up having to implement ancestorOrigin-stripping features. There are already people asking about it: http://stackoverflow.com/questions/26046030/change-window-location-ancestororigins

This feature's use is unfortunately not measured (or at least not published) by Chrome:
https://www.chromestatus.com/metrics/feature/popularity
Flags: needinfo?(dveditz)
Dan: our use case is as follows. We offer some embeddable content that for some reasons we don't want embedded in specific websites (domains with a specific category, so a blacklist). We used to use referrers for this. But people found out that if they use an allowed domain in between (so iframe in iframe) they could get around this referrer check. CSP is no use for is in this case. The only way we could detect the real domain our content is embedded in is ancestorOrigin. I'm guessing the stackoverflow question you linked is someone trying to get around this protection.
Do we actually want location.ancestorOrigins to be DOMStringList?
The Link.cpp changes and URL.cpp changes are definitely not needed.  The attribute should be placed on Location, not on URLUtils.  Also, what's with the nsGlobalWindow.cpp changes?

You shouldn't change nsIDOMLocation at all.

As for the return value... what does Chrome actually do here?  We should either copy that or use a [Cached] sequence<DOMString>.
Won't compile without Link.cpp / URL.cpp support. All other attributes are placed in URLUtils, not Location. nsGlobalWindow.cpp changes to be ignored, will be removed.

 0:13.73 ./URLBinding.cpp:317:9: error: no member named 'GetAncestorOrigins' in 'mozilla::dom::URL'

URLBinding seems to be auto-generated. Difficult to look through it all. WebIDL, *Binding, ...

Chrome is using DOMStringList, but nobody seems to like it.
Patch works, tho.
> Won't compile without Link.cpp / URL.cpp support.

It will if you don't mess with URLUtils.

> All other attributes are placed in URLUtils, not Location.

You mean except the methods on Location?  In any case, you should look at the specs: https://url.spec.whatwg.org/#api and https://html.spec.whatwg.org/multipage/browsers.html#the-location-interface -- which one is the attribute on?  ;)

> URLBinding seems to be auto-generated.

Yes, from the webidl.  Again, don't change URLUtils.
zulla, great work. Is there any reason why you didn't implement it like a DOMStringList or at least some kind of array with all the parents like it is implemented in webkit?
Any update on this?
(In reply to Erik Dubbelboer from comment #8)
> Dan: our use case is as follows. We offer some embeddable content that for
> some reasons we don't want embedded in specific websites (domains with a
> specific category, so a blacklist). We used to use referrers for this. But
> people found out that if they use an allowed domain in between (so iframe in
> iframe) they could get around this referrer check.
Well, ancestorOrigins wouldn't protect from using window.open().
Some 'bad origin' window.opens 'good origin' which embeds the iframe.
'bad origin' communicates with 'good origin' the same way as in iframe case (postMessage).
(In reply to Olli Pettay [:smaug] from comment #19)
> Well, ancestorOrigins wouldn't protect from using window.open().
> Some 'bad origin' window.opens 'good origin' which embeds the iframe.
> 'bad origin' communicates with 'good origin' the same way as in iframe case
> (postMessage).

This wouldn't really be embedding by the 'bad origin' then, it would be a whole new window from the `good origin` so that's fine by us.
The unfortunate state of the world today is that there's no one cross-browser solution if you want to prevent iframing of your content selectively.  CSP frame-ancestors is implemented by Chrome and Firefox.  XFO ALLOW-FROM is implemented by Edge and Firefox.  ancestorOrigins is implemented by Safari and Chrome.  While I'd love to see Safari and Edge support frame-ancestors, it would be very useful for Firefox to also support ancestorOrigins.  I think the argument that lack of it hasn't stopped any websites from operating can be turned around just as effectively - that it's longstanding presence in Webkit based browsers hasn't led to any privacy disasters, either.
Is there any update on this since it's now in https://html.spec.whatwg.org/multipage/browsers.html#dom-location-ancestororigins ?
The spec as written constitutes an unnacceptable privacy leak and we have communicated this clearly and repeatedly to the spec editors.  We're not going to implement it in its current form, just like we would not implement a spec that required web sites to be able to read all of a user's locally stored data.

There is a spec issue tracking changing the spec to be acceptable at https://github.com/whatwg/html/issues/1918 and we will implement the resulting spec once that issue is resolved.
Depends on: 1400501
Flags: sec-review?(dveditz)

FWIW, https://github.com/whatwg/html/pull/2480 has a proposal for a revised specification and https://github.com/web-platform-tests/wpt/pull/5402 has tests. (They are about a year old, might need rebasing. Happy to help if we prioritize this.)

Status: UNCONFIRMED → NEW
Component: DOM: Navigation → DOM: Window and Location
Ever confirmed: true
Type: defect → enhancement

Anne, do we want to implement this?

kmag says this should be easy to implement because we have WebExtension code that implements something similar.

Severity: normal → --
Flags: needinfo?(annevk)
OS: macOS → All
Hardware: x86 → All

We discussed this feature in the privacy team as it came up at https://github.com/privacycg/storage-partitioning/issues/14 as well. bz's concern about passive trackers is very much alive so we would have to mitigate that if we were to expose this. In particular, if there's no passive way (referrer) for an embedded site to know its parent, this should not reveal the parent to an embedded site.

If we apply that strictly, this would tell you at most about your parent and the only information you would get about further ancestors is how many there are.

This is even further complicated when an embedded site is navigated as the site being navigated to would never know about its parent (other than that one exists).

I'm not sure if that meets the use cases you envision for this feature.

(The HTML Standard PR doesn't account for some of these considerations and would have to be redone, if we were to pursue this further.)

Flags: needinfo?(annevk)

From the webcompat side of things, PG Slots is (accidentally?) treating location.ancestorOrigins as though it exists, but may be zero-length. This seems to just be a coding oversight, as they have fallback code which is just not correctly being falled-back-upon. Thankfully this seems to be a one-off case rather than an obviously-shared code snippet circulating online.

Severity: -- → S3
Priority: -- → P3
Webcompat Priority: --- → ?

WebCompat P3, but we'll bump it higher if we see more critical breakage in the wild.

Webcompat Priority: ? → P3

Really interested in having this feature in Firefox too. Looking forward to it!
I hope P3 means soon : )

Depends on: 1892803
Blocks: 1892803
No longer blocks: 1835377
No longer depends on: 1892803
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: