Closed Bug 1949016 Opened 4 months ago Closed 2 months ago

With first party isolation enabled BTP purges sites, not honoring user activation signals

Categories

(Core :: Privacy: Anti-Tracking, defect, P2)

Firefox 135
defect

Tracking

()

RESOLVED FIXED
139 Branch
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.

Component: Untriaged → Privacy: Anti-Tracking
Product: Firefox → Core

Hi Loreno, could you share your troubleshooting info with us? You can find it in the about:support page.

Flags: needinfo?(helohe)

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:

  1. 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
  2. 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));
})();
  1. 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.

Flags: needinfo?(helohe)
Flags: needinfo?(helohe)

(() => {
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.

Flags: needinfo?(helohe)

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!

Flags: needinfo?(helohe)

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.

Flags: needinfo?(helohe)

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:

  1. Enter the following address in the address bar: about:logging?output=profiler&modules=BounceTrackingProtection:5&output=file
  2. Select a log file destination and confirm with "set log file"
  3. Click "start logging" at the top of the page
  4. When you're done (you've reproduced the issue) click "stop logging"
  5. Share the generated log file

Thanks again for your help!

Flags: needinfo?(helohe)

I finally managed to run the log while the problem appears. I sent you an email with the file.

Flags: needinfo?(helohe)

(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?

Flags: needinfo?(helohe)

Ah, that is odd. It did not bounce and the email is correct. I will try to send it again from a different address.

Flags: needinfo?(helohe)

(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.

Flags: needinfo?(emz)

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.

Severity: -- → S3
Status: UNCONFIRMED → NEW
Ever confirmed: true
Flags: needinfo?(emz)
Priority: -- → P3
Summary: Google signs me out every time I close firefox or after ~24 hours → With first party isolation enabled BTP purges sites not honoring user activation signals
Summary: With first party isolation enabled BTP purges sites not honoring user activation signals → With first party isolation enabled BTP purges sites, not honoring user activation signals

I'll look into Fixing this for Fx140 so we can get it into ESR for tor browser.

Assignee: nobody → emz
Priority: P3 → P2
Status: NEW → ASSIGNED

FYI: I've requested input from tjr since this is a Tor Browser pref

Flags: needinfo?(tom)

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.

Flags: needinfo?(tom)

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.

Pushed by ezuehlcke@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/0640922799d5 Fix BTP not honoring user activation signals when FPI is enabled. r=anti-tracking-reviewers,bvandersloot
Status: ASSIGNED → RESOLVED
Closed: 2 months ago
Resolution: --- → FIXED
Target Milestone: --- → 139 Branch
QA Whiteboard: [qa-triage-done-c140/b139]
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: