With first party isolation enabled BTP purges sites, not honoring user activation signals
Categories
(Core :: Privacy: Anti-Tracking, defect, P2)
Tracking
()
Tracking | Status | |
---|---|---|
firefox139 | --- | fixed |
People
(Reporter: helohe, Assigned: emz)
References
(Blocks 2 open bugs)
Details
Attachments
(2 files)
User Agent: Mozilla/5.0 (X11; Linux x86_64; rv:135.0) Gecko/20100101 Firefox/135.0
Steps to reproduce:
I have cookie and tracker settings to strict, first-party isolation and also use ublock origin.
Actual results:
Lately google keeps signing me out and I have to sign back in. I suspect it has something to do with the privacy.purge_trackers.enabled preference. In another computer where this property is set to false, I am not being signed out.
Expected results:
I think some suspected tracking cookies are accidentally being deleted even though those are the cookies used for the google sign in.
Updated•4 months ago
|
Comment 1•4 months ago
|
||
Hi Loreno, could you share your troubleshooting info with us? You can find it in the about:support page.
Reporter | ||
Comment 2•4 months ago
|
||
Assignee | ||
Comment 3•4 months ago
|
||
Thanks for the report. Two things:
First party isolation is not supported in Firefox. Could you try setting privacy.firstparty.isolate
to false
, clear all site data for Google and see if the error still reproduces?
I'm also curious if this could be caused by our new bounce tracking protection feature which is enabled in ETP "strict". To find out it would be helpful if you could run a code snippet for me in the Browser Toolbox:
- Follow these instructions on how to enable and open the browser toolbox: https://firefox-source-docs.mozilla.org/devtools-user/browser_toolbox/index.html#enabling-the-browser-toolbox
- Once open in the console tab of the browser toolbox run the following code:
(Please only run code from sources you trust in this toolbox because it can expose sensitive data or break your profile if you're not careful.)
(() => {
let btp = Cc["@mozilla.org/bounce-tracking-protection;1"].getService(
Ci.nsIBounceTrackingProtection
);
let recentlyPurged = btp.testGetRecentlyPurgedTrackers({}).map((tracker) => ({
siteHost: tracker.siteHost,
purgeTime: new Date(Math.floor(tracker.purgeTime / 1000))
}));
let recentlyClassified = btp.testGetBounceTrackerCandidateHosts({}).map((tracker) => ({
siteHost: tracker.siteHost,
classifiedTime: new Date(Math.floor(tracker.timeStamp / 1000))
}));
console.debug("recently classified", JSON.stringify(recentlyClassified, null, 2));
console.debug("recently purged", JSON.stringify(recentlyPurged, null, 2));
})();
- Please share the output of the code here (recently classified, recently purged).
If we see google domains in that output it could indicate that BTP is causing this issue.
Assignee | ||
Updated•4 months ago
|
Reporter | ||
Comment 4•4 months ago
|
||
(() => {
let btp = Cc["@mozilla.org/bounce-tracking-protection;1"].getService(
Ci.nsIBounceTrackingProtection
);
…
recently classified [] debugger eval code:16:11
recently purged [
{
"siteHost": "google.com",
"purgeTime": "2025-02-19T19:55:08.185Z"
},
{
"siteHost": "data-medics.com",
"purgeTime": "2025-02-19T20:55:08.187Z"
}
] debugger eval code:17:11
undefined
I ran it a few times when google was still logged in, and the result was always empty. As soon as I noticed that I have been logged out, I ran it again and got this result above.
Assignee | ||
Comment 5•4 months ago
|
||
Thank you! "google.com" being purged is suspicious and may have led to the logout. It's surprising this would only happen every 24 hours and on shutdown though.
(1) Let's check why "google.com" was purged. It should have only been purged if you didn't recently (45 days) interact with it.
Can you run the following snippet and check if you see any Google related domains that stand out?
(() => {
let btp = Cc["@mozilla.org/bounce-tracking-protection;1"].getService(
Ci.nsIBounceTrackingProtection
);
let recentlyInteracted = btp.testGetUserActivationHosts({}).map((site) => ({
siteHost: site.siteHost,
interactionTime: new Date(Math.floor(site.timeStamp / 1000))
}));
let recentlyInteractedGoogle = recentlyInteracted.filter(({
siteHost
}) => siteHost.includes("google"));
console.debug("recently interacted", JSON.stringify(recentlyInteracted, null, 2));
console.debug("recently interacted google", JSON.stringify(recentlyInteractedGoogle, null, 2));
})();
recentlyInteracted
may contain more google domains that are not captured by my very crude "google" filter. Let me know if anything stands out. You don't have to share the entire list since that would expose a lot of your browsing history.
(2) How do you log into Google? Can you give me a list of steps I could follow to see if I can reproduce your issue? Do you log in through some country specific Google domain, e.g. google.de
?
Thanks so much for helping with the troubleshooting!
Reporter | ||
Comment 6•4 months ago
|
||
This is odd. The first code you sent still returns
recently classified [] debugger eval code:16:11
recently purged [
{
"siteHost": "google.com",
"purgeTime": "2025-02-24T08:30:07.030Z"
}
]
however the second code does not return anything:
recently interacted [] debugger eval code:15:11
recently interacted google [] debugger eval code:16:11
undefined
I use the regular google.com and gmail.com domains to sign in.
Assignee | ||
Comment 7•3 months ago
|
||
Sorry, just getting back to this now. Thanks for providing the data! It seems odd that "google.com" gets purged and there are no interactions with other Google domains. AFAIC the Google sign in page uses "accounts.google.com" which means you should have interaction for at least "google.com".
Let's look at this from another angle. Can I ask you to enable Bounce Tracking Protection logging, wait until the issue appears again and post the log here? If it contains more data than you'd like to share here you can either remove unrelated sites from the log, or send me the log via e-mail: emz@mozilla.com
Here is how you can record a log file:
- Enter the following address in the address bar:
about:logging?output=profiler&modules=BounceTrackingProtection:5&output=file
- Select a log file destination and confirm with "set log file"
- Click "start logging" at the top of the page
- When you're done (you've reproduced the issue) click "stop logging"
- Share the generated log file
Thanks again for your help!
Reporter | ||
Comment 8•3 months ago
|
||
I finally managed to run the log while the problem appears. I sent you an email with the file.
Assignee | ||
Comment 9•3 months ago
|
||
(In reply to Loreno Heer from comment #8)
I finally managed to run the log while the problem appears. I sent you an email with the file.
Awesome!
Sorry, I haven't received any email yet. Could you double check that you sent it to emz@mozilla.com and that it didn't bounce?
Reporter | ||
Comment 10•3 months ago
|
||
Ah, that is odd. It did not bounce and the email is correct. I will try to send it again from a different address.
Assignee | ||
Comment 11•3 months ago
|
||
(In reply to Loreno Heer from comment #10)
Ah, that is odd. It did not bounce and the email is correct. I will try to send it again from a different address.
This time it worked, thank you! I’ll take a look next week.
Assignee | ||
Updated•3 months ago
|
Assignee | ||
Comment 12•3 months ago
•
|
||
Looking at the logs I can indeed see google.com
being purged. Normally google.com
shouldn't get purged because you have interacted with it. With first party isolation enabled the user interaction gets partitioned though, so the user activation "protection" isn't working as expected. On purge when BTP checks for a user activation google.com, firstPartySite: ""
but the client only has one for google.com, firstPartySite: "google.com"
. With dFPI (Total Cookie Protection) in Firefox this isn't an issue because we never see top level partitioned user activation record. Only third-parties get partitionKey
set.
As on how to fix this for FPI (probably interesting for Tor?): We can record user activation stripping out firstPartySite. Beyond that FPI still has issues with BTP most likely, because of how many different OA combinations it creates. So we should strip that attribute everywhere in BTP. This will require carefully going over all places where OriginAttributes get accessed e.g. from principals or web progress.
Marking this bug as P3 since FPI is not a supported configuration, but it would be nice to fix eventually.
Workaround:
I recommend disabling FPI and switch over to dFPI (Total Cookie Protection). This has been enabled for all Firefox users since 2021.
If you don't want to disable FPI you can also disable BTP by setting privacy.bounceTrackingProtection.mode
to 0
.
Assignee | ||
Updated•3 months ago
|
Updated•3 months ago
|
Assignee | ||
Comment 13•3 months ago
|
||
I'll look into Fixing this for Fx140 so we can get it into ESR for tor browser.
Assignee | ||
Updated•3 months ago
|
Comment 14•3 months ago
|
||
FYI: I've requested input from tjr since this is a Tor Browser pref
Assignee | ||
Comment 15•3 months ago
|
||
Comment 16•3 months ago
|
||
Notation (example.com,google.com) means google.com is the firstPartyDomain and example.com is the principal's domain (aka siteHost in the first diff).
So I understand the problem, I think. We ask "Has (google.com,) had any user interaction?" and the answer is "No. (google.com,google.com) has but you didn't ask that so the answer is No." And thus BTP drops the google cookies.
The patch is changing things so now if we ever store user interaction, we store it not for (google.com,google.com) but rather just (google.com,). That seems fine.
But what about user interaction with an example.com iframe on google.com? Before, that would store user interaction for (example.com,google.com) and now we're just storing it for (example.com,). Do we want to accept that user interaction as 'true' user interaction and thus exempt it from BTP? For dFPI - because we don't have a partition value in the first-party case but we do in the third party case - it makes me think that BTP does not accept it as 'true' user interaction for example.com. This is speculation.
But if I'm correct, then we don't want to truncate firstPartyDomain all the time, we only want to truncate it when firstPartyDomain = principal's domain.
Assignee | ||
Comment 17•3 months ago
•
|
||
BTP attributes all user activation (interaction) in a given tab to the top window context's document principal:
https://searchfox.org/mozilla-central/rev/1f65969e57c757146e3e548614b49d3a4168eeb8/dom/ipc/WindowGlobalParent.cpp#1802,1806
That means even if "example.com", an iframe embedded in "google.com" receives user activation, that user activation is attributed to the top level "google.com". Since we use the document principal there is never a partition key set, so for dFPI we don't partition any BTP state. The bug here was that for FPI we did. The top window context's document principal would be "site: google.com, firstPartyDomain: google.com" in this example.
I think fully aligning dFPI and FPI behavior in BTP is the right solution. That's what the patch does by simply stripping firstPartyDomain
from OriginAttributes
in all cases.
Comment 18•2 months ago
|
||
Comment 19•2 months ago
|
||
bugherder |
Updated•2 months ago
|
Description
•