Closed Bug 565965 (doublekey) Opened 10 years ago Closed 4 years ago
Key cookies on setting domain * toplevel load domain
dbaron proposes the following, for separating 3rd party cookies between different 1st party sites: <quote> The idea is this: instead of making local-storage, cookies, etc. stored per-domain of the page setting the cookie/storage (and a domain can only access its own), it could be stored by the pair of (domain of the toplevel page) * (domain of the page doing the setting/getting). In other words, a page on facebook.com inside an iframe when the URL bar displayed cnn.com could only access storage set in the same situation. It seems like this could help with fixing some of the privacy issues related to third-party cookies and storage while avoiding the risks of breaking sites (other than the need to log in multiple times when you really did want the sharing). </quote> We should implement this after bug 565475. Perhaps with a pref to key only on setting domain if it's the same as the toplevel load domain -- allowing sites like Facebook to work seamlessly in 3rd party contexts. Also need to think about cookie storage quota.
Note that this will break one case which the proposal in bug 565965 wouldn't: 1) User loads site bank.com. 2) bank.com pops up a window that loads banklogin.com, which asks for login info. 3) Window redirects back to bank.com, which expects banklogin.com cookie to be sent. I don't know how common this pattern is. We could throw some evang effort at it, and add the pref suggested above so users have a workaround.
> I don't know how common this pattern is. We could throw some evang effort at > it, and add the pref suggested above so users have a workaround. Not to mention beta testing. :)
Sooo there's been worry that this would break things like OpenID and Facebook Connect at least. So I looked at these two cases. Facebook Connect uses a JS lightbox to throw the login dialog (http://wiki.developers.facebook.com/index.php/Authenticating_Users_with_Facebook_Connect). This counts as part of the page, rather than a popup window, and thus would be considered a third party. So double-keying would work fine here. Note that the embedder can specify they want to use a popup dialog instead, but let's say that's not the common case. OpenID probably uses redirects in general (http://www.merchantos.com/makebeta/php/single-sign-on-with-openid-and-google-part-1/), though I'm not sure about provider specifics. If we track redirects and consider them third parties -- which would require some extra mechanics -- then this would work just fine. So, how do we classify redirects? And distinguish them from link clicks or typing in the urlbar? Opera does something interesting here: by default, they consider redirects to be "unverified transactions", which are considered third party. Link clicks are verified transactions -- first party. This is actually part of RFC2965 (http://www.faqs.org/rfcs/rfc2965.html) section 3.3.6: "A transaction is verifiable if the user, or a user-designated agent, has the option to review the request-URI prior to its use in the transaction." In Opera, with "automatic redirection" turned off, I believe this means that redirects throw a page which says "this is a redirect to http://foo.com, continue?" or somesuch. Clicking that link then makes the transaction verified, and the cookies are first party. With that, I propose (where "third-party" is of course contingent on the base domains being different, and the "first-party" URI is determined once and never changes, until a new first party is generated): 1) Typing in the urlbar, loading bookmarks, other totally toplevel actions -- first-party. 2) Link clicks (href tags) -- first-party (but I'm not sure about this yet). 3) Setting document.location -- third-party. (It's hard to distinguish a user-initiated action that results in a document.location change vs. an automated change. So we have to go with third-party here.) 4) Redirects -- third-party. I'm thinking we might want to make link clicks third-party. Rationale: someone who has a regular href tag to perform a login operation, rather than using a redirect or document.location, needs that load to be considered third-party such that it works when redirected back to the first-party site. The downside is that long browsing sessions in a single tab, across multiple sites, will result in them all being considered third-party. (And thus allow behavioral tracking during that tab lifetime.) This is probably a pretty decent tradeoff to get some login cases working, but I don't have a strong opinion. There will definitely be some evangelism required around this: people should be using iframes, or JS lightboxes, or redirects to do login operations; definitely not popup windows. I think this is a pretty good sell given that popups have a maligned reputation nowadays.
Implements a simple form of double-keying (for session only; no db schema change). Also no changes to existing GetOriginatingURI() code (doesn't implement cases 3 & 4 above).
(In reply to comment #5) > FacebookConnect does indeed use a popup window for login, not a lightbox -- you > can see for yourself if you're logged out of facebook (I just tried on digg.com > and huffingtonpost.com). I assume the reason they do that is because training > users to enter their facebook credentials inside the pages of random websites > is an awesome phishing vector. Agreed, lightboxes do suck for phishing. That's what their docs said was the default, though. I tested with Digg and they are indeed using the popup window behavior. > OpenID protocol supports using popups instead of redirects and there are big > advantage to doing that as redirects are a terrible user experience especially > for unsophisticated users that get confused by leaving the sites they tried to > login on (and I'm pretty there an academic paper or two confirming this). I'm rethinking the proposal. Say we make all the proposed cases (redirects, link clicks, popup windows, document.location) first party. This means that redirects and popups are now a vector for circumventing these controls. For OpenID the above doesn't actually matter, regardless of whether they use redirects or popups -- the information is passed in a backchannel. What the new proposal would mean is that the user wouldn't need to log in for each site (assuming the provider itself allows it). For Facebook Connect, they'd need to use postMessage to get data from the popup back to the iframe like you suggest. But that's distinct from using Connect to log into a site like Digg, right? In that case, it's the same problem as OpenID, and they should solve it using the same methods. I'm not clear on how their association + login process currently works. I'm going to test. > But even with this workaround the user will still have to re-login in Facebook > they try to use FacebookConnect on every site every time the user session > cookie expires or is missing for that site. That is pretty annoying to the user > and I could very well see this leading to a significant drop-off in Facebook > users sharing or commenting on FacebookConnect-enabled sites which would make > those sites unhappy with this change as well. That's intended! Third party iframes will always be considered third party for cookie purposes. The only way to fix this case is to let iframes access cookies set in a first party context. I don't think that's a good idea. Users can whitelist facebook.com to make things work better. I'm not arguing that many let alone most users will, but it's there. > Maybe there should some sort of public RFC for this? Better protection of > users' privacy is laudable but I think this and related changes should be > thought through more carefully before being implemented. And making services > like OpenId harder to use and implement conflicts with Mozilla's goal of > furthering the OpenWeb IMHO. This does need to be carefully thought through. Proposing new methods for users to indicate they trust certain sites (or pairs of sites) will definitely be required. But waiting for people to agree on how to break the web is pretty much a non-starter, I think.
I tested huffingtonpost with my patch applied. Logging in with Connect works fine. I see those cookies go through as first party, as expected. I then see a bunch of facebook cookies get set with a first party of huffingtonpost.com; presumably that's the stuff embedded in iframes. The "share this" feature works fine, since that throws a facebook popup. And really has nothing to do with Connect. The "like this" feature is broken, though, because it's relying on the iframe to have access to the login cookies. And when it tries to get you to log in, it throws the popup, which closes since you're already logged in.
What if we make popups have a first party of window.opener? This way, all the facebook cookies for huffingtonpost.com would be under the same context. I think that'd fix this use case. And I think it's reasonable to state that popups are conceptually considered to be related to the opener.
(In reply to comment #8) > What if we make popups have a first party of window.opener? > > This way, all the facebook cookies for huffingtonpost.com would be under the > same context. I think that'd fix this use case. And I think it's reasonable to > state that popups are conceptually considered to be related to the opener. Does that mean the popup would be treated the same as an iframe? I'll refrain from commenting until I understand the change being made in this bug better. What happens when a user visits google.com and it sets a cookie and later the user visits anotherwebsite.com which has a script src pointing to google.com? When the request for the script URL is made will the cookie that was set on google.com be sent with it? It will with the current default behavior. Will that change? Thanks.
(In reply to comment #9) > Does that mean the popup would be treated the same as an iframe? Exactly. > I'll refrain from commenting until I understand the change being made in this > bug better. What happens when a user visits google.com and it sets a cookie and > later the user visits anotherwebsite.com which has a script src pointing to > google.com? When the request for the script URL is made will the cookie that > was set on google.com be sent with it? It will with the current default > behavior. Will that change? Thanks. It'll change -- that's the intent. A google.com cookie set from a toplevel URL of google.com, anotherwebsite.com, and yetanothersite.com will all be in their respective sandboxes. The trick here, as you pointed out with Facebook Connect, is to make sure that all facebook.com cookies required for anotherwebsite.com's facebook integration to work are all in the same sandbox.
By coincidence, I just ran across the XAuth initiative from Meebo, which claims support from "Google, Microsoft, MySpace, Yahoo!, Gigya, DISQUS, and Janrain" "XAuth is an open platform for extending authenticated user services across the web" It relies on the functionality that is being removed here and in fact http://xauth.org/spec/ says: "User browser preferences restricting third party cookies may interfere and return an error code."
I think that a change of this magnitude should have a wider discussion that this bug, with a wider audience than those who happened to find out about it. (I only just found out myself, and I like to think that I stay on top of major changes to our platform pretty well!) dwitte: can you start a thread in dev.platform and reference it here, at the least? this is a pretty major change and we should probably also work with other browser developers to make sure that we don't end up with a mess of different policies about cookie visibility and duration to which developers can't program confidently.
(In reply to comment #12) I know some people at Meebo and have linked them this bug just now. Hopefully they come back to us with feedback.
Hi everybody! I'm one of the front end devs at Meebo. Yes this proposal would completely disable what xauth.org does since xauth.org is exclusively loaded as a third party iframe. Example: 1) User logs into youface.com 2) youface.com integrates with us and creates an iframe to xauth.org, telling it via postMessage to save a bit that the user is logged in. 3) User logs into meebo.com, we load up xauth.org in an iframe and check via postMessage if there's a bit from youface.com (and any other integration partner). 4) If it is, we'll put youface.com as a login box front and center so it's easier for the user to see something they recognize. With this proposal, the xauth.org iframe wouldn't be in the same sandbox since the key pair has changed from youface.com-xauth.org to meebo.com-xauth.org. On top of that, part of the xauth.org effort is to allow users to see precisely what data is being passed and when they goto xauth.org, they're presented a listing of all third party local storage set there. This functionality would break as well. I'd love to hear what other web developers have to say about this. Mike Shaver mentioned a broader discussion forum for this. Where is that?
Thanks for the feedback here -- I'm (pleasantly!) surprised at the prompt nature and amount of technical feedback. This work is in its early stages, and there's more discussion to be had, to be sure. The goals of this work are unclear in this bug. To clarify, here's a wiki page I've put together that goes into more detail: https://wiki.mozilla.org/Thirdparty Comments on that are welcome. I haven't started a newsgroup/forum thread yet. I shall do so. Adam, Jian, the points you raise essentially boil down to giving the user a way to tell the browser "I trust this site to integrate with these other sites". My assertion is that we should assume a lack of such consent by default, and provide as intuitive and accessible way as possible for the user to specify it. This is up for discussion, though. I believe a solution here will include both the technical aspect (this bug), which is still preliminary; and the UX aspect, which should happen in parallel.
Is it safe to assume at this stage that this will not make Firefox 4, given how close we are to feature freeze? Prioritizing doc planning.
Absolutely. I'll take it off radar for now; we can get it back on after 4.
No need to remove dev-doc-needed; it stays off my to-do list automatically until the status is RESOLVED. I only asked because I have a planning document that says this is targeted for Fx 4, and wanted to know whether or not to expect it to land for that.
Reassigning to nobody. If anyone wants to work on this, feel free!
Assignee: dwitte → nobody
Status: ASSIGNED → NEW
As an FYI, applying this change to cookies would allow for drastic simplifications to the cookie manager. With these changes, cookies can be represented simply by the name and favicon of the top-level domain that caused them to be set. This might even make the cookie dialog usable by average users, who will more intuitively recall their relationship with a few top-level domains as opposed to hundreds of third party cookies. To demonstrate this, I've attached an example mockup I made with gimp. (Granted: The "Protection" idea could be done better: for example, there could be a "protected" pane and a "temporary" pane, and users could drag a site from one side to the other. It could also be omitted entirely). Furthermore, if all browser state (DOM Storage, client certs, HTTP Auth, cache, history) is associated with just one top-level domain, the entire privacy UI can be simplified into just this origin + favicon representation. 6 or 7 Firefox UIs could become just one. That's enough simplification to make Steve Jobs jealous ;)
Re concerns about breaking federated login, Facebook Like, and link sharing: As a transition mechanism, one could imagine an iframe attribute that causes the chrome to ask the user for permission to treat the iframe contents as top-level for cookie storage purposes. Such a permission would enable the link sharing implementations such as ShareThis and Xauth.org to avoid "nascar" logo bloat scenarios. However, this permission should not be needed forever. The Google Chrome folks have implemented a federated login selection widget in Chrome that has really good privacy features and does not require a trusted third party for the native implementation: http://web-send.org/features.html This is built into Chrome today, but has a legacy implementation sites can use for non-Chrome browsers: https://code.google.com/p/webintroducer/ Such an iframe permissions attribute could also be used to grant permission to the backwards compatible implementation, which requires trust of webintroducer.net until web-send could be implemented for Firefox.
http://yro.slashdot.org/story/11/09/03/0115241/Heises-Two-Clicks-For-More-Privacy-vs-Facebook Oh snap, did I accidentally just paste that url into this textbox? Cut and paste fail. http://priv3.icsi.berkeley.edu/ Oh man, did I do it again? This is Fail City. http://sharemenot.cs.washington.edu/ And I guess I'm running for Mayor. Not a good day. It's like this textbox is the graveyard of failed solutions to the third party privacy problem. Oh well, at least there's courage among the dead (and dearly departed). <3s and PLUR, Mike
Work to provide this feature is in progress on the Tor Browser bug tracker at https://trac.torproject.org/projects/tor/ticket/3246/
Dependencies  of this and other 3rd party isolation logic were deprecated and removed from the Mozilla codebase, so for progress please refer to the corresponding Tor Browser bug . It is possible and even likely that cookie double keying and other 3rd party isolation features merge from Tor to Mozilla in future release engineering.  https://bugzilla.mozilla.org/show_bug.cgi?id=962326  https://trac.torproject.org/projects/tor/ticket/3246/
AIUI the new (but not much-discussed) Safari "Allow from current website only" cookie (and site data) policy is effectively (but not exactly) double-key. FWIW I've been using it for a few months now, and the breakage is very slight; only a few issues with Paypal integration and a few OAuth burps. I wonder if it'd be useful to have a (very) small spec for double-key out there, to align implementation behaviour and give sites some understanding of what's going on (so that we can avoid said problems with paypal, oauth, etc.) Maybe not right away, but before it gets too big...
For what it's worth, I'm less keen on the double-key idea than I used to be, because it seems relatively simple for sites to work around it using redirects (i.e., if ID of user is not linked from domain X, redirect the toplevel page briefly to a page at domain X, which will redirect back to a URL at the original domain with a token identifying the user).
Don't disagree -- this (putting state in URLs as a workaround) has always been the case for *any* cookie control mechanism. However, doing so a) takes a lot more coordination / work for the site, and b) is much more apparent; it's hard to escape the conclusion that the site is trying to do something to circumvent the users' wish for privacy. I.e., while it's possible to work around double-keying, the workaround has a lot of "friction", and so it still may be worth doing.
(In reply to David Baron [:dbaron] (UTC-8) (needinfo? for questions) from comment #30) > it seems relatively simple for sites to work around it using redirects > [...] > Documents originating from HTTP redirects are considered 1st party and thus the workaround Dave described would (not without the chance of user scrutiny) render double keyed matching useless. I'm not sure if the workaround would apply after changing the defined context of HTTP redirected documents to 3rd party however, which was what Dan commented on in https://bugzilla.mozilla.org/show_bug.cgi?id=565965#c3. Even if the aforementioned spaghetti context based solution were defeated then Mark's reasoning of forcing 3rd parties through expensive hoops might be worth considering.
Hi David, The way I see it, the rationale you are providing is the observation that a second vulnerability exists even after fixing the first vulnerability. Without any other context, the natural conclusion from that observation is to close both vulnerabilities. However, there are exceptional conditions that have been stated: 1. It could break legitimate single sign-on services. 2. It is easy to work around. 3. There are other ways to fix the problem. Note that #2 actually mitigates #1. If it is easy to work around by ad networks, then it is easy to work around by single sign-on services, especially since it is typically the ad networks who also provide the single sign-on services, for example: Google, Apple, and Microsoft. Regarding #3, another way to fix the problem, there is a simple conception of the problem that reveals that other measures of the problem always have and always will end up being half-measures. *Theory* Device identity is a device resource that needs transparent, well-managed authorization from the end-user in the same way that other device resources are managed, like the geolocation, camera, and microphone services. These resources are managed on a per-origin basis, in compliace with the same-origin policy. I believe everyone involved already knows at some level that this is the case, but are reluctant to address the problem in this way. There are controversial effects, but now that we have a descriptive theory to analyze the effects of the various techniques, the techniques may be formally analyzed, and mitigations, likely borrowed from the implementations of other resources, may be developed to address the controversial effects. With a descriptive theory, other methods end up being exposed as incomplete versions of this approach. For example, the automatic first-party trust based merely on visits may be seen as a partial implementation of this that: 1. leaves out user intent. 2. is not transparent. 3. is based on a false assumption, 4. Is even more trivial to work around by just sending pixels from each ad network's portal site that everyone will eventually visit. The hosting of pixels on portals renders the assumption of trust insignficant, a "distinction without a difference". If the rationale that a second vulnerability exists applies to double-keying, then it seems to also apply to the first-party implied-trust feature. Furthermore, implied trust on each visit contradicts the rationale for existing resource management on geolocation and microphone access. It also is in direct violation of the same-origin policy that is soon going to be an IETF RFC standard. For a Mozilla project that claims to support end-user privacy, this is a totally unacceptable solution. For an ad network, it is a great solution. To the point, after Apple became a successful ad network, it defaulted configuration to this feature to weaken its previous default configuration that blocked all third-party cookies. This is not the right solution for Mozilla. Another example is the approach that the EFF has taken with Privacy Badger. This is the best alternative that I have seen that doesn't actually address the vulnerability directly. It is the only proposed alternative I have seen which is capable of addressing the navigation-related, horizontal isolation issues that still remain after keying the resources properly. However, in its current form, I view it like a good anti-virus solution on top of a very insecure system. Its basic design issue is that it uses complicated definitions for what a tracker is, rather than the simple definition that any communication between origins could be a tracker, and working from that premise to manage the acceptance of such communications. My feeling is that it is trying too hard to understand the semantics of a communication, rather than flagging and getting user input about the semantics. But that isn't Privacy Badger's fault. They have to use that design today because it has to look at trackers no matter which origin they are communicating with, and the amount of prompts would be ridiculous. If browsers properly managed origin resources, and exposed a clean API for trust-management plugins, then Privacy Badger's technique could be applied where it belongs: dealing only with helping the user navigate cross-origin identifiers. My hunch is that there is another issue that is the real problem. My impression is that the real problem is that no one wants to actually close the second vulnerability, because it would be too disruptive. Too disruptive for both: 1. End users. 2. Ad networks which fund online development. Mozilla has stated that it prioritizes personal privacy, so it needs to satisfy that no matter what happens with #2. I don't think anything needs to be stated about #2 except that the market needs to adjust, and will ultimately adjust. What remains is an argument for balancing end-user privacy with end-user functionality. However, what is happening is that ad networks are conflating their needs with the needs of end-users, because the ad networks have no basis for an argument solely on behalf of their own needs. In reality, the supposed end-user nuisances are actually features that end-users want and need. We have seen this with many other advancements in security designed to defeat trojans, and these trackers are indeed trojans. In the end, the nuisances provide a reasonable boundary that ultimately developors figure out how to work within. Again, the Privacy Badger approach can mitigate a lot of concerns related to this. *Implementation* A straightforward implementation is to add a prompt for "origin crossings" (as I call them) that aren't trusted, and manage identity just as you would manage any other device resource. In this case, each origin's set of resources are a separate logical resource that needs per-origin authorization, so the trust needs to be per origin-to-origin crossing. These prompts are a way to provide "horizontal isolation" between origins, even after the "vertical isolation" problems are fixed. For example, we already have something like: "Allow content.cloudservice.com to enter full-screen mode -- Just now? Never? Always?" It can be translated to "Allow msnbc.com to redirect to facebook.com -- Just now? Never? Always?" What I do is ask the user whether they want to follow the full link, or just go to the origin's root so that the user can find the link through safer means. *Reference Implementation* David, you may remember me from an email I sent to you earlier, asking about the rationale for these issues, and you brought up the same rationale to me then. I hadn't actually considered it before, so it was a good point. But I quickly came up with the horizontal isolation solution, and mentioned it in a couple sentences, which didn't seem to convey the idea to you properly, probably because I didn't yet get the theoretical relationship to managing identity as a device resource, which I think explains it much more clearly. I told you that I would return with a more proper solution. I have now addressed those issues in a fairly straightforward way by providing a simple theoretical framework, and also a *reference* *implementation*, so that people can see how it works in the real world. I have implemented both vertical, process-level orgin isolation, and horizontal, origin-crossing isolation on top of webkit as a proof of concept, based on the surf.suckless.org minimal browser. I finished just a few days ago, and have been using it as my main browser, to test. My main test is using gmail to test the single sign-on case that everyone is concerned about, and logging in to pay bills. Gmail actually works just fine, but with one caveat: I needed to map the origins of mail.google.com and accounts.google.com together, just because at one step in the process they relied on a shared cookie instead of forwarding the identifier in the redirected URL. In my browser implementation, I was able to just use a symbolic link to map the isolated browser profiles together, expanding the vertical isolation to the necessary group of origins, and now gmail works perfectly, just as before. It could also be as simple as having the implementation's getOrigin() function return meta-origins that have been configured, so that the mapping is much more integrated. I paid a utility bill since I started using it, and that worked just fine because that kind of setup naturally needs to pass identifers in the URIs anyway, because those kinds of payment platforms integrate more easily with utilities in that way. Otherwise, both would need to connect back-end systems, which is fairly risky for a utility to do compared to just passing an identifier through the client, and having the utility pull the payments from the payment platform either manually or automatically, a much less risky method than allowing the payment processor to connect to the utility directly. Logging into bugzilla now, of course, worked just fine. To test out my implementation: 1. The base browser code may be found at http://surf.suckless.org/ 2. My disk cache patch may be found at: http://lists.suckless.org/dev/1501/25069.html 3. My vertical and horizontal same-origin policy patch may be found at: http://lists.suckless.org/dev/1501/25070.html My ultimate goal is to persuade everyone that a complete isolation such as this is very possible, and to put forward a descriptive theory and an example of complete origin isolation in the wild so that discussion can be qualified by demonstrations which clarify the effects.
Whiteboard: [evang-wanted] → [evang-wanted][necko-backlog]
this is linked to from the tor browser design doc so i'm tagging this to put it in the tor backlog.
Whiteboard: [evang-wanted][necko-backlog] → [evang-wanted][necko-backlog][tor]
This bug was resolved by bug 1260931 (implemented the First Party Isolation feature), and further polished by bug 1301406 (the case in e10s mode). The implementation was verified by bug 1312541.
Status: NEW → RESOLVED
Closed: 4 years ago
Resolution: --- → DUPLICATE
Duplicate of bug: 1260931
You need to log in before you can comment on or make changes to this bug.