After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 792130 - SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY is too strict
SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY is too strict
Status: RESOLVED FIXED
Product: libsoup
Classification: Core
Component: HTTP Transport
2.60.x
Other Linux
: Normal normal
: ---
Assigned To: Michael Catanzaro
libsoup-maint@gnome.bugs
Depends on:
Blocks: 793336
 
 
Reported: 2018-01-02 15:45 UTC by Michael Catanzaro
Modified: 2018-03-22 15:29 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
cookie-jar: use base domain to decide if cookie is third party (5.38 KB, patch)
2018-01-10 21:21 UTC, Michael Catanzaro
none Details | Review
cookie-jar: Implement third-party cookie grandfathering (10.00 KB, patch)
2018-01-10 21:21 UTC, Michael Catanzaro
none Details | Review
cookie-jar: use base domain to decide if cookie is third party (5.38 KB, patch)
2018-01-10 21:34 UTC, Michael Catanzaro
none Details | Review
cookie-jar: Implement third-party cookie grandfathering (8.77 KB, patch)
2018-01-10 21:34 UTC, Michael Catanzaro
reviewed Details | Review
cookie-jar: use base domain to decide if cookie is third party (6.25 KB, patch)
2018-03-08 03:02 UTC, Michael Catanzaro
none Details | Review
cookie-jar: use base domain to decide if cookie is third party (6.16 KB, patch)
2018-03-08 03:07 UTC, Michael Catanzaro
committed Details | Review

Description Michael Catanzaro 2018-01-02 15:45:23 UTC
SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY is documented to work as follows:

"""accept all cookies set by the main document loaded in the application using libsoup. An example of the most common case, web browsers, would be: If http://www.example.com is the page loaded, accept all cookies set by example.com, but if a resource from http://www.third-party.com is loaded from that page reject any cookie that it could try to set. For libsoup to be able to tell apart first party cookies from the rest, the application must call soup_message_set_first_party() on each outgoing SoupMessage, setting the SoupURI of the main document. If no first party is set in a message when this policy is in effect, cookies will be assumed to be third party by default."""

That seems intuitively the correct way to implement a third party cookie blocking policy, but it is too strict. It breaks, for example, notifications on google.com. For this policy to be usable, it needs to match the policy of the only other web browser that currently blocks third party cookies by default: Safari. I don't pretend to understand all the details of how Safari decides to block cookies -- it's based on machine learning in the WebKit layer -- and it's certainly not libsoup's job to implement anything resembling that. But there is one simple rule that it would be nice for libsoup to implement: if a website has previously set a cookie, it should always be treated as a first party and should always be able to set cookies in the future. That is, if a SoupCookieJar already contains a cookie for http://www.third-party.com it should always be available to http://www.third-party.com even though the first party on the outgoing SoupMessage may be different. That seems like a big privacy weakness, but it's a requirement to closer match Safari's behavior and avoid breaking the web. Then WebKit should manage additional complex cookie policy (resource load statistics, aka intelligent tracking prevention) itself.

If we do not change libsoup, then we'll have to implement this policy at the WebKit level, and WebKit will no longer be able to use SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY. It will have to use SOUP_COOKIE_JAR_ACCEPT_ALWAYS and implement third-party cookie filtering itself. I assume this is possible, so we don't *have* to change libsoup, but libsoup's SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY is probably not useful to have if we don't change it, as I assume only web browsers are likely to be interested in SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY.
Comment 1 Carlos Garcia Campos 2018-01-03 10:38:35 UTC
Would it be enough to compare the TLD instead of the host?
Comment 2 Michael Catanzaro 2018-01-03 16:56:35 UTC
(In reply to Carlos Garcia Campos from comment #1)
> Would it be enough to compare the TLD instead of the host?

No, that's only enough in the specific case of google.com, and we should not do that unless we are sure that's what Safari is doing (I doubt it is).
Comment 3 Carlos Garcia Campos 2018-01-04 07:42:59 UTC
(In reply to Michael Catanzaro from comment #2)
> (In reply to Carlos Garcia Campos from comment #1)
> > Would it be enough to compare the TLD instead of the host?
> 
> No, that's only enough in the specific case of google.com, and we should not
> do that unless we are sure that's what Safari is doing (I doubt it is).

Do we know any other case that is broken because of this? Why do we have to do what Safari does? Do we even know what Safari does? Why not what chromium or firefox do, since we have the code to know exactly what they do? I've googled about this and I've found this:

https://github.com/speedarius/third-party-cookie-tester

According to that Safari does what you suggests (I haven't checked it myself though). But it also says that both Safari and Chrome consider subdomains as first party for cookies. So, if we do that in libsoup we would fix the google issue, which the only one I know. Then, we can decide whether to make it less strict or not.

I think WebKit is indeed the only user of SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY.
Comment 4 Michael Catanzaro 2018-01-04 17:28:25 UTC
(In reply to Carlos Garcia Campos from comment #3)
> Do we know any other case that is broken because of this?

Not any real websites, but I presume there must be more that we don't know about.

I suspect it may be responsible for WebKit test http/tests/resourceLoadStatistics/grandfathering.html failing, though. With ITP, third-party cookies from a domain are supposed to be allowed for 24 hours after a first-party visit to that domain. That must not be working properly, currently.

> Why do we have to do what Safari does?

Because only Safari blocks third-party cookies by default, and only Safari implements intelligent tracking prevention, so the only way to be web compatible and also block third party cookies is to match Safari as closely as possible.

The alternative would be to stop blocking third party cookies, and not enable intelligent tracking prevention.

> Do we even know what Safari does?

Nope, not really.

> Why not what chromium
> or firefox do, since we have the code to know exactly what they do? I've
> googled about this and I've found this:
> 
> https://github.com/speedarius/third-party-cookie-tester
> 
> According to that Safari does what you suggests (I haven't checked it myself
> though). But it also says that both Safari and Chrome consider subdomains as
> first party for cookies. So, if we do that in libsoup we would fix the
> google issue, which the only one I know.

Excellent, good discovery! We should implement that too.

> Then, we can decide whether to make
> it less strict or not.

I think we should make both changes. I agree that the subdomain change is more important.
Comment 5 Michael Catanzaro 2018-01-10 21:21:00 UTC
(In reply to Michael Catanzaro from comment #4)
> I suspect it may be responsible for WebKit test
> http/tests/resourceLoadStatistics/grandfathering.html failing, though.

Nope, it's not.
Comment 6 Michael Catanzaro 2018-01-10 21:21:28 UTC
Created attachment 366617 [details] [review]
cookie-jar: use base domain to decide if cookie is third party

Our third-party cookie blocking is too strict. Safari is the only major
browser that blocks third-party cookies by default, so the only way for
SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY to be web compatible is for it to
match Safari as closely as possible. And Safari does not appear to
consider the full domain when deciding whether to block a third-party
cookie, it only considers the base domain. Reports indicate that Firefox
and Chrome behave similarly if the user chooses to block third-party
cookies in those browsers.

This fixes, in particular, notifications on google.com domains.
Comment 7 Michael Catanzaro 2018-01-10 21:21:32 UTC
Created attachment 366618 [details] [review]
cookie-jar: Implement third-party cookie grandfathering

Safari is the only browser that blocks third party cookies by default,
so if we want SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY to be
web-compatible, it's going to have to match Safari's behavior. Currently
libsoup does not allow subresources to set cookies unless they match the
domain of the main resource. Safari makes an exception for domains that
have been previously visited, so we should too.

WebKit will layer intelligent tracking prevention on top of this,
allowing cookie grandfathering for only a single day.

This could alternately be implemented as a new
SoupCookieJarAcceptPolicy instead of a modification to
SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY.
Comment 8 Michael Catanzaro 2018-01-10 21:27:15 UTC
(In reply to Michael Catanzaro from comment #7)
> This could alternately be implemented as a new
> SoupCookieJarAcceptPolicy instead of a modification to
> SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY.

The argument for adding a new policy is that this change makes it real easy for websites to circumvent third-party cookie blocking by just redirecting the main resource to the desired domain and back, or loading it in e.g. a small frame.

The argument for not adding a new policy is that WebKit is probably the only real user of SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY, so there's not much value in adding a fourth cookie policy, if it means nobody will be using SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY anymore. Semantically, this changes the definition of third party from "a domain that does not match the main resource" to "a domain the user has never visited directly."

I have no strong preference either way.
Comment 9 Michael Catanzaro 2018-01-10 21:34:08 UTC
Created attachment 366619 [details] [review]
cookie-jar: use base domain to decide if cookie is third party

Our third-party cookie blocking is too strict. Safari is the only major
browser that blocks third-party cookies by default, so the only way for
SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY to be web compatible is for it to
match Safari as closely as possible. And Safari does not appear to
consider the full domain when deciding whether to block a third-party
cookie, it only considers the base domain. Reports indicate that Firefox
and Chrome behave similarly if the user chooses to block third-party
cookies in those browsers.

This fixes, in particular, notifications on google.com domains.
Comment 10 Michael Catanzaro 2018-01-10 21:34:12 UTC
Created attachment 366620 [details] [review]
cookie-jar: Implement third-party cookie grandfathering

Safari is the only browser that blocks third party cookies by default,
so if we want SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY to be
web-compatible, it's going to have to match Safari's behavior. Currently
libsoup does not allow subresources to set cookies unless they match the
domain of the main resource. Safari makes an exception for domains that
have been previously visited, so we should too.

WebKit will layer intelligent tracking prevention on top of this,
allowing cookie grandfathering for only a single day.

This could alternately be implemented as a new
SoupCookieJarAcceptPolicy instead of a modification to
SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY.
Comment 11 Michael Catanzaro 2018-01-16 01:03:10 UTC
(In reply to Michael Catanzaro from comment #10)
> Created attachment 366620 [details] [review] [review]
> cookie-jar: Implement third-party cookie grandfathering

I think we may not want to commit this one until we have implemented cookie storage partitioning (another overdue feature), but we definitely need to land the base domain change now to fix Google.
Comment 12 Carlos Garcia Campos 2018-01-29 16:36:21 UTC
I agree we should try the first one, but not the second one yet.
Comment 13 Michael Catanzaro 2018-01-31 01:51:15 UTC
Comment on attachment 366620 [details] [review]
cookie-jar: Implement third-party cookie grandfathering

Removing this one from the patch tracker. We can revisit in the future once libsoup supports cookie storage partitioning.
Comment 14 Michael Catanzaro 2018-01-31 01:52:44 UTC
Review of attachment 366619 [details] [review]:

This one is still needed to fix google.com.
Comment 15 Claudio Saavedra 2018-02-01 13:40:05 UTC
Review of attachment 366620 [details] [review]:

My take on this is that strictly speaking, changing the semantics of SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY wouldn't be a good idea. I understand that it is possible that WebKit is the only user of this but there is no way we can be certain of this and, after all, this is a library with an API that we need to respect. I am instead inclined towards adding a new policy that WebKit can use.
Comment 16 Claudio Saavedra 2018-02-01 14:01:12 UTC
Review of attachment 366619 [details] [review]:

While this would fix google.com notifications, I am worried that this would open the door for unrelated sites in different subdomains to misbehave. But if this is really what other browsers do, maybe we have no alternative.
Comment 17 Michael Catanzaro 2018-02-01 14:30:41 UTC
(In reply to Claudio Saavedra from comment #15)
> Review of attachment 366620 [details] [review] [review]:
> 
> My take on this is that strictly speaking, changing the semantics of
> SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY wouldn't be a good idea. I understand
> that it is possible that WebKit is the only user of this but there is no way
> we can be certain of this and, after all, this is a library with an API that
> we need to respect. I am instead inclined towards adding a new policy that
> WebKit can use.

OK; it was hard for me to decide between adding a new policy and changing the existing one. If I revive this patch in the future, I'll add a new policy.

(In reply to Claudio Saavedra from comment #16)
> Review of attachment 366619 [details] [review] [review]:
> 
> While this would fix google.com notifications, I am worried that this would
> open the door for unrelated sites in different subdomains to misbehave. But
> if this is really what other browsers do, maybe we have no alternative.

This seems to be the behavior of at least Safari, Firefox, and Chrome, so I think we should just change it.
Comment 18 Claudio Saavedra 2018-02-02 13:48:02 UTC
> This seems to be the behavior of at least Safari, Firefox, and Chrome, so I think we should just change it.

I'm ok with the change.
Comment 19 Michael Catanzaro 2018-02-02 16:22:02 UTC
Can I commit it, or do you want more time to review it...?
Comment 20 Claudio Saavedra 2018-02-05 14:44:38 UTC
Review of attachment 366619 [details] [review]:

Pushed this.
Comment 21 Dan Winship 2018-02-06 14:38:57 UTC
(In reply to Claudio Saavedra from comment #15)
> My take on this is that strictly speaking, changing the semantics of
> SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY wouldn't be a good idea.

The semantics of that flag are not rigorously defined. The docs merely give an "example" of one sort of thing that setting the flag might do, without suggesting that that's the only thing it does.
Comment 22 Claudio Saavedra 2018-02-07 14:22:39 UTC
OK, in that case let's keep it simple and keep the same flag if there are no other sensible uses of it.
Comment 23 Michael Catanzaro 2018-02-07 16:51:11 UTC
Well the main problem here is fixed.

I'll file a new bug to implement grandfathering if, in the future, we determine this is necessary.
Comment 24 Claudio Saavedra 2018-03-05 17:30:53 UTC
I'm reverting this, according to Michael it's causing issues.
Comment 25 Michael Catanzaro 2018-03-08 02:28:20 UTC
See https://bugs.webkit.org/show_bug.cgi?id=183245 for details. Corrected patch incoming.
Comment 26 Michael Catanzaro 2018-03-08 03:01:52 UTC
I've added a new test for this too.

Carlos, can you confirm that this looks right? I remember you also got tripped up by the leading dot in the cookie domain recently.
Comment 27 Michael Catanzaro 2018-03-08 03:02:02 UTC
Created attachment 369421 [details] [review]
cookie-jar: use base domain to decide if cookie is third party

Our third-party cookie blocking is too strict. Safari is the only major
browser that blocks third-party cookies by default, so the only way for
SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY to be web compatible is for it to
match Safari as closely as possible. And Safari does not appear to
consider the full domain when deciding whether to block a third-party
cookie, it only considers the base domain. Reports indicate that Firefox
and Chrome behave similarly if the user chooses to block third-party
cookies in those browsers.

This fixes, in particular, notifications on google.com domains.
Comment 28 Michael Catanzaro 2018-03-08 03:07:41 UTC
Created attachment 369422 [details] [review]
cookie-jar: use base domain to decide if cookie is third party

Remove unnecessary strdup
Comment 29 Claudio Saavedra 2018-03-08 11:17:17 UTC
I see that the only change is the added normalization of the domain and the new test to check for the regression. I think it look fine to me, not sure if we should ask for a code freeze break though, your call.
Comment 30 Ting-Wei Lan 2018-03-08 14:09:59 UTC
Attachment 369422 [details] works for me on FreeBSD Bugzilla and Phabricator.
Comment 31 Michael Catanzaro 2018-03-08 15:18:54 UTC
(In reply to Claudio Saavedra from comment #29)
> I see that the only change is the added normalization of the domain and the
> new test to check for the regression. I think it look fine to me, not sure
> if we should ask for a code freeze break though, your call.

I'll ask for the freeze break.
Comment 32 Michael Catanzaro 2018-03-11 23:12:43 UTC
It's looking like this one might not get a freeze break. If so, consider committing it for 2.62.1 instead. Just don't want this to wait another six months.
Comment 33 Michael Catanzaro 2018-03-22 15:29:38 UTC
Attachment 369422 [details] pushed as d5952f2 - cookie-jar: use base domain to decide if cookie is third party