Closed Bug 1362834 Opened 7 years ago Closed 7 years ago

Prevent browser.cookies APIs from interacting with internal cookies

Categories

(WebExtensions :: Frontend, defect, P3)

53 Branch
defect

Tracking

(Not tracked)

RESOLVED WONTFIX

People

(Reporter: simon, Assigned: bsilverberg)

References

Details

(Whiteboard: [cookies] triaged)

Attachments

(1 file)

User Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:53.0) Gecko/20100101 Firefox/53.0
Build ID: 20170421105455

Steps to reproduce:

1. get cookies via cookies.getAll({})
manually compare the result with cookie information from settings -> privacy - yep, that matches
2. for each cookie object, transform it to info object {name, url, storeId}
3. pass each info object to cookies.get() or cookies.remove() 


Actual results:

For all info objects, cookies.get() gets the cookie, cookies.remove() removes the cookie and returns Promise.resolve(infoObject),
except for one specific cookie from google.com (name:"NID", domain:".google.com"), where in get() and remove() return a Promise.resolve(null).

Observed on Linux 53/54/55 and Windows 53.
Just to be a little more precise, trying to remove the google cookie does not only return the promise of null, it also does not remove the cookie, which is my actual concern.
And again something to add: it occasionally _does_ work, but not regularly from my view.
Assignee: nobody → bob.silverberg
Whiteboard: investigate
I tried to reproduce this on Nightly on OS X and was unable to do so. Could you provide a reduced code sample that reproduces this for you?
Flags: needinfo?(simon)
That background script demonstrates the issue. After visiting a site where I get the google cookie (e.g. https://www.nytimes.com/) and then trigger tryCookieAPI(), I get this output:

getAll(): google cookie present: {"name":"NID","value":"[I cut that]","domain":".google.com","hostOnly":false,"path":"/","secure":false,"httpOnly":true,"session":false,"expirationDate":1510337745,"storeId":"firefox-default"}
get(): cookie not present.
remove(): cookie not present.
getAll(): google cookie present: {"name":"NID","value":"[I cut that]","domain":".google.com","hostOnly":false,"path":"/","secure":false,"httpOnly":true,"session":false,"expirationDate":1510337745,"storeId":"firefox-default"}
Flags: needinfo?(simon)
Attachment #8866898 - Flags: feedback+
Here is another example to work with console:

const log = p => p.then(r => console.log(JSON.stringify(r)));

// get all, filter google
log(browser.cookies.getAll({}).then(cs => cs.filter(c => c.domain=='.google.com').pop()))

That yields the google cookie:
{"name":"NID","value":"...","domain":".google.com","path":"/","secure":false," ...}

Try to get it with get() (and use http instead https because secure=='false')
log(browser.cookies.get({name:'NID',url:'http://google.com/'}))

That works for all other cookies I'vs seen so far, but returns null for the google cookie.
Interestingly, even when I set the values as filter for getAll(), it doesn't work for the google cookie either (but does for all others):

log(browser.cookies.getAll({name:'NID', domain:'.google.com'}))
Thanks for the examples, Matthias. Unfortunately I am unable to reproduce the issue on both Nightly and Release on my platform, which is OS X 10.12.5. I tried both using the background script you provided and using the console commands from comment 5, and in all cases I was able to see the cookie called NID and I was able to remove that cookie.

Can you provide us with the manifest.json file that you are using with this test extension? I'm wondering if it has something to do with host permissions.
Flags: needinfo?(simon)
See Also: → 1364782
Bob, thanks for your investigation. It never came to my mind that keys from manifest.json could play a role. So I played around a bit, especially with permissions - and always got the same issue. After I hit onto some interesting things that isolate the issue (see below), I doubt that manifest keys matter here. Anyway, I will attachment my manifest.

I finally realized that when I visited http://google.com directly, I _was_ able to do cookies.get() and cookies.remove() with proper results. I always visited other sites before and got that cookie from google.com anyway, so I tried to track that request down which is responsible. I didn't find any. Every site I visited didn't get me the google cookie, but when I checked my preferences and cookies.getAll(), it was there. Then I found out that the cookie came from the safebrowsing requests Firefox makes internally to prevent malicious requests...

tl;dr
cookies.get() and cookies.remove() work with cookies which come from responses after a user visits a site. They do not seem to work properly with cookies which result from internal requests Firefox makes, e.g. to use the safebrowsing API from Google.

And a final hint to reproduce that: Firefox seems to cache results from safebrowsing.google.com. I had to start with a fresh profile every time I wanted to see that internal call to safebrowsing.google.com.
Flags: needinfo?(simon)
(In reply to Matthias Simon from comment #7)
> cookies.get() and cookies.remove() work with cookies which come from
> responses after a user visits a site. They do not seem to work properly with
> cookies which result from internal requests Firefox makes, e.g. to use the
> safebrowsing API from Google.

Is the safebrowsing cookie one example among many ("e.g.") or is that the only case? We did specific work to isolate the safebrowsing cookie so it would be separate from the user's logged-in Google identity while still fulfilling Google's requirement for our use of the safebrowsing API. We delete this cookie periodically (every week, I think).

Pretty sure we need to keep this cookie isolated from the web extension APIs that deal with normal browsing cookies. Francois?
Flags: needinfo?(francois)
(In reply to Daniel Veditz [:dveditz] from comment #8)
> Is the safebrowsing cookie one example among many ("e.g.") or is that the
> only case?

It's special since it's using a Safe Browsing-specific origin attribute (introduced in bug 1320402), but perhaps there are other cases too (containers?).

> We delete this cookie periodically (every week, I think).

I don't believe that we ever delete it.

> Pretty sure we need to keep this cookie isolated from the web extension APIs
> that deal with normal browsing cookies. Francois?

I don't see a problem with letting extensions remove this cookie as well. In fact, a cookie-clearing extension should be able to clear all cookies just like the equivalent built-in functionality.

However, we should probably tag it in a different way from the web-accessible cookies.
Flags: needinfo?(francois)
(In reply to François Marier [:francois] from comment #9)
> It's special since it's using a Safe Browsing-specific origin attribute
> (introduced in bug 1320402), but perhaps there are other cases too
> (containers?).

Sorry, I just wanted to be more generic here because I don't know about other potential requests Firefox makes "internally". The google cookie from safebrowsing was the only one I saw not to be deleted.
 
> I don't see a problem with letting extensions remove this cookie as well. In
> fact, a cookie-clearing extension should be able to clear all cookies just
> like the equivalent built-in functionality.

I made that cookie-cliearing add-no, that's how I discovered that issue. To users that are concerned about privacy, it might appear strange that especially the google cookie won't disappear from that list of cookies.

Just want to point out that the cookie still can be removed through the browsers privacy settings. So why restrict WebExt API here? But when you decide that cookie should not do be deleted with WebExt, I suggest to not return it as a result of cookies.getAll(). It would appear inconsistent if you cannot remove it with cookies.remove() afterwards.
(In reply to Matthias Simon from comment #10)
> Just want to point out that the cookie still can be removed through the
> browsers privacy settings. So why restrict WebExt API here? But when you
> decide that cookie should not do be deleted with WebExt, I suggest to not
> return it as a result of cookies.getAll(). It would appear inconsistent if
> you cannot remove it with cookies.remove() afterwards.

In case my reply wasn't clear, I do think that the WebExt API should include the Safe Browsing cookie as part of both cookies.getAll() and cookies.remove().

The only question I have is: can we flag it somehow as an internal cookie?
(In reply to François Marier [:francois] from comment #11)
> 
> In case my reply wasn't clear, I do think that the WebExt API should include
> the Safe Browsing cookie as part of both cookies.getAll() and
> cookies.remove().
> 
> The only question I have is: can we flag it somehow as an internal cookie?

There must be something about the cookie that flags it to Firefox, because it currently is not being removed. I'll see if I can figure out what that is. Are you suggesting we should also flag it in the API output as an internal cookie? I don't see any reason why we cannot do that, once I figure out what in the cookie metadata indicates that it is an internal cookie.
(In reply to Bob Silverberg [:bsilverberg] from comment #12)
> Are you suggesting we should also flag it in the API output as an
> internal cookie?

I think it would be a useful distinction for privacy add-ons. A lot of people make the mistake of thinking that we set a web-accessible Google cookie as soon as you create a fresh profile. Flagging these internal cookies in a different way would help dispel that myth.

> I don't see any reason why we cannot do that, once I figure
> out what in the cookie metadata indicates that it is an internal cookie.

Not sure whether that helps, but in the cookies DB, it's in the originAttributes field:

  $ sqlite3 cookies.sqlite 
  SQLite version 3.8.7.1 2014-10-29 13:59:56
  Enter ".help" for usage hints.
  sqlite> select baseDomain, originAttributes, name, host from moz_cookies;
  statcounter.com||__cfduid|.statcounter.com
  mozilla.org||_ga|.mozilla.org
  mozilla.org||_gid|.mozilla.org
  google.com|^firstPartyDomain=safebrowsing.86868755-6b82-4842-b301-72671a0db32e.mozilla|NID|.google.com
(In reply to François Marier [:francois] from comment #13)
> (In reply to Bob Silverberg [:bsilverberg] from comment #12)
> > Are you suggesting we should also flag it in the API output as an
> > internal cookie?
> 
> I think it would be a useful distinction for privacy add-ons. A lot of
> people make the mistake of thinking that we set a web-accessible Google
> cookie as soon as you create a fresh profile. Flagging these internal
> cookies in a different way would help dispel that myth.
> 

How do you think we should flag this for consumers of the API? Should there be a property called isInternal, or do you have another suggestion?

> > I don't see any reason why we cannot do that, once I figure
> > out what in the cookie metadata indicates that it is an internal cookie.
> 
> Not sure whether that helps, but in the cookies DB, it's in the
> originAttributes field:
> 
>   $ sqlite3 cookies.sqlite 
>   SQLite version 3.8.7.1 2014-10-29 13:59:56
>   Enter ".help" for usage hints.
>   sqlite> select baseDomain, originAttributes, name, host from moz_cookies;
>   statcounter.com||__cfduid|.statcounter.com
>   mozilla.org||_ga|.mozilla.org
>   mozilla.org||_gid|.mozilla.org
>  
> google.com|^firstPartyDomain=safebrowsing.86868755-6b82-4842-b301-
> 72671a0db32e.mozilla|NID|.google.com

Thanks François. We have access to the originAttributes when we are converting cookies from Firefox into API output, so we can easily look for and address this. What exactly defines a cookie as internal? Can we just look for "safebrowsing" in the firstPartyDomain of originAttributes?
Flags: needinfo?(francois)
(In reply to Bob Silverberg [:bsilverberg] from comment #14)
> Thanks François. We have access to the originAttributes when we are
> converting cookies from Firefox into API output, so we can easily look for
> and address this. What exactly defines a cookie as internal? Can we just
> look for "safebrowsing" in the firstPartyDomain of originAttributes?

Maybe we could simply flag all cookies with non-empty originAttributes as "internal"?
Flags: needinfo?(francois)
Whiteboard: investigate → investigate, cookies
This issue was discussed in a meeting and it was agreed upon that WebExtensions should not be able to interact with internal cookies such as the Google safebrowsing cookie. This means the "unable to get" and "unable to remove" behaviours reported in this bug are expected, but we need to do a bit of research to see what other cookie methods can currently be used to interact with internal cookies and change the behaviour to hide the cookies from those methods as well.
Status: UNCONFIRMED → NEW
Ever confirmed: true
Priority: -- → P3
Summary: cookies.get() and cookies.remove() don't see specific cookie from google.com → Prevent browser.cookies APIs from interacting with internal cookies
Whiteboard: investigate, cookies → [cookies] triaged
(In reply to Bob Silverberg [:bsilverberg] from comment #17)
> This issue was discussed in a meeting and it was agreed upon that
> WebExtensions should not be able to interact with internal cookies such as
> the Google safebrowsing cookie.

So cookie management WebExtensions won't be able to access all of the cookies that the built-in pref UI has access to?
(In reply to François Marier [:francois] from comment #18)
> (In reply to Bob Silverberg [:bsilverberg] from comment #17)
> > This issue was discussed in a meeting and it was agreed upon that
> > WebExtensions should not be able to interact with internal cookies such as
> > the Google safebrowsing cookie.
> 
> So cookie management WebExtensions won't be able to access all of the
> cookies that the built-in pref UI has access to?

Yes, that is exactly what we are proposing. It was felt that we needn't allow extension code to interact with these internal cookies, but the user should still have a way of deleting them manually, if they really want to, and they can do that via the preferences UI. Daniel was on board with this decision. Do you disagree?
Flags: needinfo?(francois)
(In reply to Bob Silverberg [:bsilverberg] from comment #19)
> Yes, that is exactly what we are proposing. It was felt that we needn't
> allow extension code to interact with these internal cookies, but the user
> should still have a way of deleting them manually, if they really want to,
> and they can do that via the preferences UI. Daniel was on board with this
> decision. Do you disagree?

I won't pretend I've considered all of the factors that you have thought about. My recommendation in comment 11 was based on the fact that removing these internal cookies won't break anything, and that users of cookie managers might find it surprising that their privacy add-ons can't manage all of the cookies that Firefox can.

The "internal" label may be a little misleading in that it suggests that these cookies are somehow necessary for Firefox to operate correctly. That's of course not the case since we have to deal with missing cookies in fresh profiles and also after users clear all of their cookies.
Flags: needinfo?(francois)
(In reply to François Marier [:francois] from comment #20)
> (In reply to Bob Silverberg [:bsilverberg] from comment #19)
> > Yes, that is exactly what we are proposing. It was felt that we needn't
> > allow extension code to interact with these internal cookies, but the user
> > should still have a way of deleting them manually, if they really want to,
> > and they can do that via the preferences UI. Daniel was on board with this
> > decision. Do you disagree?
> 
> I won't pretend I've considered all of the factors that you have thought
> about. My recommendation in comment 11 was based on the fact that removing
> these internal cookies won't break anything, and that users of cookie
> managers might find it surprising that their privacy add-ons can't manage
> all of the cookies that Firefox can.
> 

Yes, I can see both sides of the argument. I'm fine either way, but I guess as we discussed and decided it in the meeting we should stick with what's described in comment #17. I realize this is the opposite of what you suggested François.

> The "internal" label may be a little misleading in that it suggests that
> these cookies are somehow necessary for Firefox to operate correctly. That's
> of course not the case since we have to deal with missing cookies in fresh
> profiles and also after users clear all of their cookies.

This is a good point, although I don't think we're actually labeling anything as "internal" - that's just a term we're using in the bug. Based on your suggestion in comment #15, for our WebExtensions code, we will treat any cookies with non-empty originAttributes as "internal" and will therefore exclude them.
(In reply to Bob Silverberg [:bsilverberg] from comment #21)
> ..., for our WebExtensions code, we will treat
> any cookies with non-empty originAttributes as "internal" and will therefore
> exclude them.

I hope that you don't literally mean non-empty originAttributes, since private browsing mode is also stored in originAttributes.
Furthermore, the firstPartyDomain flag appears to not only be used for safebrowsing, but also for other purposes.
See:
- https://wiki.mozilla.org/Security/FirstPartyIsolation
- Bug 1381197 (=WebExtensions cookies API is broken when first-party isolation is enabled).
See Also: → 1381197
(In reply to Rob Wu [:robwu] from comment #22)
> (In reply to Bob Silverberg [:bsilverberg] from comment #21)
> > ..., for our WebExtensions code, we will treat
> > any cookies with non-empty originAttributes as "internal" and will therefore
> > exclude them.
> 
> I hope that you don't literally mean non-empty originAttributes, since
> private browsing mode is also stored in originAttributes.
> Furthermore, the firstPartyDomain flag appears to not only be used for
> safebrowsing, but also for other purposes.
> See:
> - https://wiki.mozilla.org/Security/FirstPartyIsolation
> - Bug 1381197 (=WebExtensions cookies API is broken when first-party
> isolation is enabled).

In comment 15 that's exactly what François suggested, unless I am misinterpreting. François, can you please clarify exactly how you recommend that we identify a cookie as "internal" and therefore one which should be excluded from all WebExtensions API operations?
Flags: needinfo?(francois)
(In reply to Bob Silverberg [:bsilverberg] from comment #23)
> In comment 15 that's exactly what François suggested, unless I am
> misinterpreting. François, can you please clarify exactly how you recommend
> that we identify a cookie as "internal" and therefore one which should be
> excluded from all WebExtensions API operations?

I hadn't considered first-party isolation :(

Maybe we shouldn't ignore these cookies but instead expose the origin attribute somehow.

Ethan, Tom, do you guys have any opinion on how we should expose that via the Web Extension API?
Flags: needinfo?(tom)
Flags: needinfo?(ettseng)
Flags: needinfo?(francois)
(In reply to François Marier [:francois] from comment #24)
> (In reply to Bob Silverberg [:bsilverberg] from comment #23)
> > In comment 15 that's exactly what François suggested, unless I am
> > misinterpreting. François, can you please clarify exactly how you recommend
> > that we identify a cookie as "internal" and therefore one which should be
> > excluded from all WebExtensions API operations?
> 
> I hadn't considered first-party isolation :(
> 
> Maybe we shouldn't ignore these cookies but instead expose the origin
> attribute somehow.
> 
> Ethan, Tom, do you guys have any opinion on how we should expose that via
> the Web Extension API?

I can't speak to the question of "Should or shouldn't we allow retrieving/clearing the SafeBrowsing cookies' (which was earlier decided to be 'No') - but we should allow Web Extensions to manipulate cookies relating to OA.

Perhaps the answer is 'Cookie Stores'.  I'm looking at the API at https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/cookies and https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/cookies/CookieStore

> Windows in different browsing modes may use different cookie stores — a private browsing/incognito mode window, for instance, will use a separate cookie store from a non-incognito/private window.

Replace all instances of 'Window[s]' with 'Tab[s]' and you have a decent representation of how First Party Isolation works. Tab A (on a.com) has a separate cookie store from Tab B (on b.com) and both may contain (different) cookies for subdomain.com.

I don't know what the 'id' attribute of CookieStore currently uses ('normal' vs 'private' ?) but that could be expanded to be the exact string of the originAttributes column from the sqlite table, or it could be a hash of it, or it could be an hmac of it (if for some reason we wanted to protect the literal contents of that column, but I don't think we would need to.)

If we expose OA via the CookieStore mechanism, I _think_ it should allow the full range of functionality:
 - You can enumerate all cookies for all domains, as long as you look in all stores
 - You can delete all cookies from all stores
 - You can move cookies between stores[0]

For the SafeBrowsing cookie, it seems like we have a very limited number of super-special internal cookies (just one?) and we would need to special-case it to prevent manipulation.

Anyway, this is an off-the-cuff thought, so there's probably reasons why it wouldn't work, but maybe it's a start?


[0] This functionality could enable a very interesting power-user extension for FPI: The ability to 'merge' domains either after-the-fact or in a loop. This would mean that I could turn on FPI, but tell the extension 'Merge github.com and gitlab.com firstPartyDomain cookies so the sites function well together.'
Flags: needinfo?(tom)
Flags: needinfo?(ettseng)
(In reply to Tom Ritter [:tjr] from comment #25)
> For the SafeBrowsing cookie, it seems like we have a very limited number of
> super-special internal cookies (just one?) and we would need to special-case
> it to prevent manipulation.

If we're going to expose OA in the API, then what I said in comment 9 applies. I don't think we need to prevent the Safe Browsing cookie from being cleared by extensions.
(In reply to Tom Ritter [:tjr] from comment #25)
> (In reply to François Marier [:francois] from comment #24)
> > (In reply to Bob Silverberg [:bsilverberg] from comment #23)
> > > In comment 15 that's exactly what François suggested, unless I am
> > > misinterpreting. François, can you please clarify exactly how you recommend
> > > that we identify a cookie as "internal" and therefore one which should be
> > > excluded from all WebExtensions API operations?
> > 
> > I hadn't considered first-party isolation :(
> > 
> > Maybe we shouldn't ignore these cookies but instead expose the origin
> > attribute somehow.
> > 
> > Ethan, Tom, do you guys have any opinion on how we should expose that via
> > the Web Extension API?
> 
> Perhaps the answer is 'Cookie Stores'.  I'm looking at the API at
> https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/cookies and
> https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/cookies/
> CookieStore
> 
> > Windows in different browsing modes may use different cookie stores — a private browsing/incognito mode window, for instance, will use a separate cookie store from a non-incognito/private window.
> 
> Replace all instances of 'Window[s]' with 'Tab[s]' and you have a decent
> representation of how First Party Isolation works. Tab A (on a.com) has a
> separate cookie store from Tab B (on b.com) and both may contain (different)
> cookies for subdomain.com.
> 
> I don't know what the 'id' attribute of CookieStore currently uses ('normal'
> vs 'private' ?) but that could be expanded to be the exact string of the
> originAttributes column from the sqlite table, or it could be a hash of it,
> or it could be an hmac of it (if for some reason we wanted to protect the
> literal contents of that column, but I don't think we would need to.)
> 

The ID of cookie stores have the following formats, and are used as follows:
- "firefox-default" - normal browsing mode (OA = {privateBrowsingId: 0, userContextId: 0})
- "firefox-private" - private browsing mode (OA = {privateBrowsingId: 1}
- "firefox-container-[integer]" - container tabs (OA = {userContextId: ...})

It seems that you are suggesting that if FPI is enabled, that all IDs get another tag, e.g. "firefox-default:fpd=example.com". This has a few implications:
- (bad) The number of "cookie stores" can become very large without explicit cookie store creation requests (currently these stores are small and can be managed through the contextualIdentities API - https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/contextualIdentities)
- (good?) Any API where cookieStoreId is/becomes supported (e.g. in the tabs API) will conceptually view tabs with different first-party domains as being in separate contexts.

Because of the first point, I am inclined to support FPI by adding an extra attribute to the cookies API, instead of inflating the concept of cookieStoreId.
To support firstPartyDomain for tabs, I think that we can do something like this:
- Tabs without context inherit the firstPartyDomain from the URL.
- Tabs with an openerTabId (1238314) will inherit the firstPartyDomain from that original tab.


Given this information, which option do you prefer, and why?
Flags: needinfo?(tom)
Flags: needinfo?(francois)
(In reply to Rob Wu [:robwu] from comment #27)
> The ID of cookie stores have the following formats, and are used as follows:
> - "firefox-default" - normal browsing mode (OA = {privateBrowsingId: 0,
> userContextId: 0})
> - "firefox-private" - private browsing mode (OA = {privateBrowsingId: 1}
> - "firefox-container-[integer]" - container tabs (OA = {userContextId: ...})
> 
> It seems that you are suggesting that if FPI is enabled, that all IDs get
> another tag, e.g. "firefox-default:fpd=example.com". This has a few
> implications:
> - (bad) The number of "cookie stores" can become very large without explicit
> cookie store creation requests (currently these stores are small and can be
> managed through the contextualIdentities API -
> https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/
> contextualIdentities)
> - (good?) Any API where cookieStoreId is/becomes supported (e.g. in the tabs
> API) will conceptually view tabs with different first-party domains as being
> in separate contexts.


Yes that's accurate.

 
> Because of the first point, I am inclined to support FPI by adding an extra
> attribute to the cookies API, instead of inflating the concept of
> cookieStoreId.

This could work... but it has a lot of corner cases. (Well I suppose everything has a lot of corner cases!)  Some of the ones I can think of in this situation:

- Cookies may or may not have a value in the firstPartyDomain attribute. (If FPI is not enabled in about:config, all cookies will have this attribute blank.) 
- If the attribute is set, while FPI is turned off, the cookie will not be used.
- Some Cookies will not have a value (those set before FPI is turned on) while others will (those set after FPI is turned on)
- If FPI is enabled, cookies must be set with this attribute correctly set, otherwise they won't be used. If FPI gets turned off, these cookies won't be used.
- Mixing FPI and Containers is weird, but ought to work correctly despite being complicated.



One drawback of making it an attribute is that we begin to expose the complicated-ness of FPI in the default configuration (when FPI is not enabled). We could try to guide the user by detecting the current FPI config setting and behaving differently... If FPI is off, it rejects attempts to set a cookie with a non-blank fpi attribute, and you only see cookies that have a blank attribute. (Maybe we expose all non-blank-attribute cookies, if one exists, in a single separate store 'firefox-isolated'?)

And then if FPI is on: it rejects attempts to set a cookie with a blank attribute, and you only see cookies that have an attribute with a value. Maybe we expose all blank-attribute cookies in a single store 'firefox-nonisolated' or something. (There's also still the question of what to do with cookies with a userContextId AND a firstPartyDomain. And what to do about trying to put FPI cookies into a container store...)





> To support firstPartyDomain for tabs, I think that we can do something like
> this:

How does userContextId inherit via this API? I presume if they have a openerTabId they get it from there, otherwise they get the default?

> - Tabs without context inherit the firstPartyDomain from the URL.

This part is fine.

> - Tabs with an openerTabId (1238314) will inherit the firstPartyDomain from
> that original tab.

This part is not. In this situation, I would violate FPI lots of places. It makes sense to inherit the container (userContextId) this way, but we should always be determining the firstPartyDomain by the top level URL.



> Given this information, which option do you prefer, and why?

They all seem bad in some way or another. :)  I'm not sure which I prefer at this time...
Flags: needinfo?(francois)
Hey Rob, what would be the mechanism to move this forward? (At least to the point of "Well we know what we want to do, even if it's going to wait to be implemented.) Should we have a brainstorm session realtime or something?
Flags: needinfo?(tom) → needinfo?(rob)
(In reply to Tom Ritter [:tjr] from comment #29)
> Hey Rob, what would be the mechanism to move this forward? (At least to the
> point of "Well we know what we want to do, even if it's going to wait to be
> implemented.) Should we have a brainstorm session realtime or something?

Depends on the use cases that we want to support.
- At the very least, a cookie manager should be able to operate correctly when FPI is enabled.
- A nice-to-have is to allow add-ons to assist users in migrating cookies from non-FPI to FPI and vice versa.

I think that all cookie APIs (cookies.get/getAll/remove/set methods, cookies.Cookie type) should be extended with the firstPartyDomain attribute.

When FPI is disabled (default):
- The firstPartyDomain attribute is optional in get/remove/set, defaulting to an empty string.
- Consequently, cookies with a non-empty firstPartyDomain are not shown by default.
- The behavior for getAll is:
  * If firstPartyDomain is not set, default to empty string.
  * If firstPartyDomain is set to a string, use it.
  * If firstPartyDomain is set to null or undefined, do not filter the list of cookies by firstPartyDomain value.
  (this can be implemented by declaring "optional": "omit-key-if-missing" in extensions/schemas/cookies.json).

When FPI is enabled:
- The firstPartyDomain attribute is mandatory in get/remove/set and should be set to a string.
- The firstPartyDomain attribute in getAll should be a string or null/undefined (it cannot be unset).
- Cookies without a firstPartyDomain should have an empty string as a value for firstPartyDomain.
- Optional: cookies.set rejects the request to create new cookies without a non-empty firstPartyDomain value.

Implementation notes:
- The cookies.json schema should declare firstPartyDomain as optional for the methods.
- The implementation in ext-cookies.js must check the firstPartyDomain value according to the FPI setting (with the above semantics).
- getAll in cookies.json must use "optional": "omit-key-if-missing" instead of "optional":true, to allow the implementation to distinguish a set value and an unset value (otherwise the schema validator will fill in null (or another default value) when the value is not set).


I have designed the API in this way, because:
- Extensions without explicit support for FPI won't see FP cookies.
- Extensions without explicit support for FPI won't work when the browser has enabled FPI.
- Extensions are able to support both FP and FPI cookies at the same time if they want to.
Flags: needinfo?(rob)
That approach sounds good to me!
The implementation of comment 30 would better be attached to bug 1381197.

This bug is (apparently) about limiting access to internal cookies (=safebrowsing cookie).

Bob, in comment 17 it has been decided that WebExtensions should not have access to Safebrowsing cookies. Why is that?
As an author of a cookie manager with focus on privacy, I surely want to be able to delete the NID cookie, because this is a persistent identifier that can be used by Google to de-anonimize a Firefox user.
Flags: needinfo?(bob.silverberg)
Comment 8 and comment 9 contain some of the discussion around this. I know that in a meeting we had Daniel suggested we disallow access to the cookie via WebExtensions, but the conversation in the bug makes that seem possibly unnecessary. Sorry for digging back up such an old conversation, but Daniel, can you make a further comment on this? How do you feel about reversing that decision?
Flags: needinfo?(bob.silverberg) → needinfo?(dveditz)
François made it clear that nothing breaks if we allow this cookie to be cleared. My concern has mainly been about whether cookie-manipulating extensions have enough context, and containers and first-party-isolation are more important contexts to fix.
Flags: needinfo?(dveditz)
Based on the above, I'm going to close this as wontfix. I have copied Rob's comment 30 into bug 1381197 where it is more useful.
Status: NEW → RESOLVED
Closed: 7 years ago
Resolution: --- → WONTFIX
Product: Toolkit → WebExtensions
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: