Open wanderview opened 7 years ago
I might be missing something, but doesn't this apply to much more than just BroadcastChannel? E.g. fetch() for server-side communication to another tab, or otherWindow.postMessage(), or more...
How would the server know about another tab? That would only apply if the user is logged in. postMessage()
applies, but you cannot generally get handles to windows across tabs.
I think for BroadcastChannel
we should point this out as a fingerprinting concern, but double-keying seems more appropriate than disabling, but maybe both should be allowed for now.
This also applies to SharedWorker
.
Also don't forget it allows insecure https-nested-under-http frames to communicate with secure top level https frames. Its a similar problem.
Edit: But maybe that is solved by double-keying as well.
@annevk What is double-keying?
@wanderview How is BroadcastChannel
different from window.open
and window.opener
? Why is storage the barometer of whether or not BroadcastChannel
should be disabled?
window.open()
creates a visible top-level window popup. If the succeeds from a 3rd party iframe then they have pretty much already interacted with the frame and opt'ed in to whatever it wants to do. (At least conceptually to me.)
I think BroadcastChannel
is different. If you happen to have socialmediasite.com open in one tab, and then do some random browsing in other tabs. We should not let nested socialmediasite.com iframes in those random other tabs communicate with the top level socialmediasite.com. Or at least not if the user has asked for those nested iframes to be isolated by blocking 3rd party cookies, etc. Otherwise socialmediasite.com can track you across other, unrelated browsing you do while you have one of their tabs opened anywhere in the browser.
Double-keying or first-party isolation would help here, but may not completely solve it. AIUI some of the webkit solutions here promote any origin you have interacted with as a first party to first party status as a nested iframe. So it doesn't help with the situation I describe above.
@wanderview Adding sandbox=""
attribute to the <iframe>
should prevent communication from <iframe>
in a separate tab with window.opener
when the tab is opened with <a target="_blank">
https://plnkr.co/edit/kEha0MitTDjZEdFrUnPg?p=preview.
Are you suggesting that the communication should be restricted by default?
I'm not concerned about sandboxed iframes that result in an opaque origin. Those can't BroadcastChannel to other Windows because the origin won't match.
This is more about contexts like 3rd party iframes that are not sandboxed, but the user has disabled 3rd party cookies.
@wanderview Not gathering what the concern is? Can you fork the linked plnkr to demonstrate?
I don't know how I can describe it better than https://github.com/whatwg/html/issues/3054#issuecomment-331886122 and https://github.com/whatwg/html/issues/3054#issuecomment-352300561.
If a user has blocked 3rd party cookies that is a pretty strong signal they don't want these iframes to track them across different sites. Something like BroadcastChannel would let these 3rd party iframes communicate to another top level frame of the same origin and persist tracking information to disk.
Anyway, I'm happy to just fix this in gecko. @annevk wanted me to raise a spec issue, but its unclear to me how much the spec covers things like blocking 3rd party iframe cookies.
Why would <iframe>
's on different tabs having the same origin be considered 3rd party? The specification does not appear to mention blocking 3rd party cookies relevant to BroadcastChannel
.
It is not clear from perspective here how "access to storage" is related to the case? As mentioned at an earlier comment SharedWorker
can communicate between browsing contexts having the same origin
. The storage
event can also be utilized to achieve comparable communication between browsing contexts as BroadcastChannel
and SharedWorker
.
Why would
That's why I filed an issue. To fix this in the spec. (But honestly I don't know if the spec handles 3rd party iframe cookie blocking anyway.)
And its not that the frames are considered 3rd party to each other, its if they are 3rd party to their parent tab.
It is not clear from perspective here how "access to storage" is related to the case? As mentioned at an earlier comment SharedWorker can communicate between browsing contexts having the same origin. The storage event can also be utilized to achieve comparable communication between browsing contexts as BroadcastChannel and SharedWorker.
Yes, I want to disable SharedWorker in 3rd party iframes with storage disabled as well:
https://bugzilla.mozilla.org/show_bug.cgi?id=1401359
The goal is to avoid letting iframes that we have set a policy of "no storage" to escape to another window/tab of same origin that is allowed to access storage. These escapes are bypasses around the "block cookies in 3rd party iframes" restrictions.
Maybe you don't care about this privacy bypass, but its clear that our users do. If we are going to have a "block 3rd party iframe storage/cookies" option, then it should prevent these bypasses of the mechanism as well.
Maybe you don't care about this privacy bypass, but its clear that our users do.
"care" is not relevant to what is technically possible.
There is not, nor should there be any expectation of "privacy" in any communications, certainly not within the realm of the current implementation of the World Wide Web (interwebs).
If we are going to have a "block 3rd party iframe storage/cookies" option, then it should prevent these bypasses of the mechanism as well.
The first step would be to clearly define "3rd party".
Do you mean, for example, if a user is viewing a document at github.com on two separate tabs, and the user logs in at one of those tabs the notification is displayed at the tab where the user is not logged in to "Reload" the document? In essence what you are describing would prevent that notification at github.com, yes?
It must be noted here that the term "privacy" itself is not clearly defined at the specification.
https://github.com/whatwg/html/issues/3304
//cc @wanderview @domenic @annevk
In WebKit, we'd probably want to disable BroadcastChannel in frames that don't have access to their origin's first-party storage, or at least partition/double-key it in the same way we do for cache, cookies and other storage mechanisms in a third-party context. We don't currently implement BroadcastChannel but we'd have to look at this when/if we do. Tagging @johnwilander
WebKit has a feature called Intelligent Tracking Prevention (ITP). ITP aims to prevent third parties from tracking a user's browsing around the web using client-side state. Though our first version was imperfect, we are committed to closing evasion techniques and not creating new ones. For example, we recently blocked the use of HSTS state as a tracking vector.
Our primary technique for this is partitioning, (AKA double-keying). You can see the details in the blog post I linked.
BroadcastChannel would create an evasion technique by bridging partitioned third-party contexts and first-party contexts, thus allowing third-party contexts to read the first-party storage and track you.
(BTW, if you think of other possible evasion techniques with future or existing web technologies, bugs at http://bugs.webkit.org/ will be welcome.)
WebKit has a feature called Intelligent Tracking Prevention (ITP). ITP aims to prevent third parties from tracking a user's browsing around the web using client-side state.
We should not infer that any web usage is not tracked or capable of being prevented from being tracked.
Open source browsers themselves perform metrics as to use of specific browser implementations and usage of the browser itself.
Again, "3rd party" and "third party" are not as yet clearly defined.
"3rd party iframes" are commonly known in browsers to mean iframes such that:
// this is conceptually true in a "3rd party" iframe
self.origin !== window.top.origin
Of course, you can't actually evaluate that in actual web content because I believe window.top.origin
is not accessible from cross-origin iframes.
How would Blob URL
s being requested from
// this is conceptually true in a "3rd party" iframe
self.origin !== window.top.origin
be addressed?
@guest271314 I'd like to ask you to please take that elsewhere as it's not important to address this issue. All the HTML Standard needs to note is that this is a fingerprinting concern. If at some point we want to standardize third-party cookie policies and their implications on various APIs we can take a more holistic view, but that's not needed now and out-of-scope here.
@annevk I agree that the use case is established, but I think it's about using BroadcastChannel to defeating stateful tracking protections, rather than for fingerprinting. Fingerprinting usually refers to tracking without use of stored client-side state at all, by passively observing the behavior of the browser or the user.
(Sorry if this distinction is too fussy; I just wanted to make sure everyone is clear about the use case.)
Currently the <!--INSERT FINGERPRINT-->
mechanism (to highlight privacy issues) is used for localStorage
as well as things like navigator.languages
. It seems reasonable to use it here too, but perhaps we should rename/reframe it somehow.
It would be nice to align with broader industry use of privacy-related terms, though maybe not super important if it’s only in spec comments. “Tracking” or “web tracking” is the usual term for the category of things that include state-based tracking, fingerprinting, IP address based tracking, etc. That’s the terminology the EFF uses, for sample. Tracking methods using client-side state are sometimes called “super cookies”. Fingerprinting includes browser fingerprinting and behavioral fingerprinting.
Navigator.languages is useful for browser fingerprinting (a type of tracking), while the risk from LocalStorage is a kind of tracking (state-based tracking, aka super cookies), but technically not fingerprinting.
There are also sometimes privacy concerns other than tracking in the web platform. For example, an API to expose the user’s golocation would have a privacy risk that is not about web tracking.
@wanderview Do the Chromium --site-per-process
and --isolate-origins
flags achieve the requirement that is being addressed by this issue?
@wanderview Do the Chromium --site-per-process and --isolate-origins flags achieve the requirement that is being addressed by this issue?
No. That moves 3rd party iframes to a separate process, but AFAIK does not change the origin of the iframes in any way. Since BroadcastChannel
works across processes to matching origins it would not help here.
In contrast webkit's ITP/"double-keying" and firefox's "first party isolation" approaches effectively change the origins of 3rd party iframes. So they do help here because BroadcastChannel from one of these iframes won't match the origin of any top level frames.
Edit: But firefox does not have first party isolation turned on by default, so we can't rely on it here.
This issue is dormant for the moment, but in case it revives:
Per @othermaciej, it's true that BroadcastChannel
can be used as part of a strategy to defeat ITP's partitioning! But a partitioned BroadcastChannel
is still useful. I'm using it (in Firefox and Chrome) to communicate between same-origin sibling iframes embedded in a third-party context. This allows me to propagate user state across these embedded interfaces when the user has disabled third-party storage (which also disables sessionStorage
in those browsers). This use case would still work fine if BroadcastChannel
were partitioned—but not if it were disabled completely in this storage-less context.
See https://github.com/whatwg/html/issues/5803 for partitioning BroadcastChannel
. Apparently Gecko does this already.
Should we close this issue, and roll things into the general storage-partitioning effort? Or is there still merit in disabling BroadcastChannel in some cases, when storage is explicitly disabled?
I guess the first question is, in our partitioned-storage future, do we ever expect storage to be disabled?
I think closing this issue and do the partitioning in https://github.com/whatwg/html/issues/5803 makes sense. If it turns out that there are some other cases where we want to disable BroadcastChannel
, we can reopen this issue then.
Thanks @andymatuschak for pinging this thread and helping us consolidate our thinking!
As discussed in https://github.com/whatwg/storage/pull/93 and issues referenced from there I think HTML needs to invoke obtain a storage key for this API.
data:text/html,<script> console.log(new BroadcastChannel("test")) </script>
is a simple test for this unrelated to partitioning; it constructs something in Firefox, but throws in Chrome.
Currently we disable access to storage for a variety of reasons:
If one of these windows uses BroadcastChannel it could in theory communicate tracking information to another tab the user has open which can then write it to disk.
Also, consider an https:// iframe in an insecure http:// parent. It can BroadcastChannel to other https:// windows that may be considered secure. Should it be disabled in this situation as well?
I had thought this was an implementation detail, but @annevk asked me to write a spec issue.