Open Bug 1836333 Opened 2 years ago Updated 21 days ago

Private mode: Cookies / cookie settings are deleted when tab changes to background

Categories

(Firefox for Android :: Privacy, defect, P3)

Firefox 115
All
Android
defect

Tracking

()

UNCONFIRMED

People

(Reporter: Webworkr, Unassigned)

References

Details

(Whiteboard: [fxdroid][group2])

Attachments

(1 file)

19.51 KB, application/octet-stream
Details

User Agent: Mozilla/5.0 (Android 13; Mobile; rv:109.0) Gecko/115.0 Firefox/115.0

Steps to reproduce:

Open a new tab in private mode. Cookies or cookie settings (e.g. rejection) are set after a query.

Switch to another private tab, go to standard mode or switch completely to another app (multitasking).

Return to the private tab from the beginning.

Actual results:

Instead, cookies or cookie settings are often deleted. Result: Sessions are ended, e.g. logouts follow. Cookie queries pop up again.

Expected results:

Set cookies and settings are retained as long as the private tab is open.

This bug report is based on https://github.com/mozilla-mobile/fenix/issues/19850. The phenomenon also currently occurs under modified hardware (Samsung Galaxy A13 5G (SM-A136B), Android 13).

Related:
https://bugzilla.mozilla.org/show_bug.cgi?id=1709483
https://bugzilla.mozilla.org/show_bug.cgi?id=1701303

The severity field is not set for this bug.
:jonalmeida, could you have a look please?

For more information, please visit BugBot documentation.

Flags: needinfo?(jonalmeida942)

This sometimes happens on trim memory in private mode. (Switch back from other applications and the page is auto reloaded and the cookie has been dropped.)

The phenomenon continues to occur:

Nightly
119.0a1 (Build #2015973953), 418fb80f34+
GV: 119.0a1-20230913092556
AS: 119.20230913050406

The phenomenon continues to occur:

Fennic
117.0.1 (Build #1170100), 9ebc7544df+
GV: 117.0-20230909004609
AS: 117.0

I have noticed the same thing. If I log in to Twitter in a private tab, and don't use Firefox for some time (a few hours), I get logged out.

Firefox 118.1.0
Android 11 / Samsung phone

Severity: -- → S4
Component: General → Privacy
Priority: -- → P3
Flags: needinfo?(jonalmeida942)

I encountered this too. This happens especially on system low memory. (I forgot i've already added a comment)

I guess this may related to when on low memory , how firefox handling close and restore gecko session or how gecko session itself restoring.

This could easily reproduce with android's "Developer options" > "Background process limit" > "No background processes" and switch background then foreground.

  1. Set Andoird's "Developer options" > "Background process limit" > "No background processes"
  2. Open Firefox and visit https://setcookie.net in Private Mode and set a cookie.
  3. Switch Firefox background and (open another application and) then switch Firefox foreground to observe the cookie is dropped.

Also it could reproduce on GeckoView Example.

Attached file cookielogs.txt

GeckoViewExample logs with am start -n org.mozilla.geckoview_example/.GeckoViewActivity --es env0 MOZ_LOG=PBContext:5,BrowsingContext:5,BrowsingContextSync:5 and logcat -d Gecko:V '*:S'

some Logs (full logs attached )

28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/BrowsingContextSync Transaction::Apply(#4, local): ExplicitActive(1->2)
28884 28923 I Gecko   : [Child 28884: Main Thread]: D/BrowsingContextSync Transaction::Apply(#4, ipc): ExplicitActive(1->2)
28884 28923 I Gecko   : [GFX1-]: CompositorBridgeChild receives IPC close with reason=AbnormalShutdown
28836 28868 I Gecko   : [GFX1-]: CompositorBridgeChild receives IPC close with reason=AbnormalShutdown
28836 28872 I Gecko   : [Parent 28836, IPC I/O Parent] WARNING: waitid failed pid:28884 errno:10: file /gecko-dev/ipc/chromium/src/base/process_util_posix.cc:244
28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/BrowsingContextSync Transaction::Apply(#3, local): Closed(false->true)
28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/BrowsingContextSync Transaction::Apply(#3, local): IsActiveBrowserWindowInternal(true->false)
28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/BrowsingContextSync Transaction::Apply(#4, local): IsActiveBrowserWindowInternal(true->false)
28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/BrowsingContextSync Transaction::Apply(#4, local): IsUnderHiddenEmbedderElement(false->true)
28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/BrowsingContext Parent: Detaching 0x00000004 from 0x00000000
28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/PBContext DecreasePrivateCount: Private browsing context count 1 -> 0
28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/PBContext DecreasePrivateCount: last-pb-context-exited fired
28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/BrowsingContext Parent: Detaching 0x00000003 from 0x00000000
28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/BrowsingContext Creating 0x00000005 in Parent
28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/BrowsingContext Parent: Connecting 0x00000005 to 0x00000000 (private=0, remote=0, fission=0, oa=)
28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/BrowsingContextSync Transaction::Apply(#5, local): Loading(false->false)
28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/BrowsingContextSync Transaction::Apply(#5, local): CurrentInnerWindowId(0->10)
28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/BrowsingContextSync Transaction::Apply(#5, local): GVAudibleAutoplayRequestStatus(0->0) GVInaudibleAutoplayRequestStatus(0->0)
28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/BrowsingContextSync Transaction::Apply(#5, local): CurrentInnerWindowId(10->10)
28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/BrowsingContextSync Transaction::Apply(#5, local): Name(->59dce3d36797461cac724ae53136e1e6)
28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/BrowsingContextSync Transaction::Apply(#5, local): DefaultLoadFlags(0->0)
28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/BrowsingContextSync Transaction::Apply(#5, local): CurrentLoadIdentifier(Nothing->Some(12))
28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/BrowsingContextSync Transaction::Apply(#5, local): CurrentLoadIdentifier(Some(12)->Some(12))
28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/BrowsingContextSync Transaction::Apply(#5, local): CurrentInnerWindowId(10->10)
28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/BrowsingContextSync Transaction::Apply(#5, local): HasLoadedNonInitialDocument(false->true)
28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/BrowsingContextSync Transaction::Apply(#5, local): CurrentLoadIdentifier(Some(12)->Nothing)
28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/BrowsingContext Creating 0x00000006 in Parent
28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/BrowsingContext Parent: Connecting 0x00000006 to 0x00000000 (private=1, remote=1, fission=0, oa=^privateBrowsingId=1)
28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/PBContext IncreasePrivateCount: Private browsing context count 0 -> 1
28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/BrowsingContextSync Transaction::Apply(#6, local): HasSessionHistory(false->true)
28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/BrowsingContextSync Transaction::Apply(#6, local): ExplicitActive(2->1) EmbedderInnerWindowId(0->10) UseGlobalHistory(false->true) FullscreenAllowedByOwner(true->true) EmbedderElementType(Nothing->Some(browser)) MessageManagerGroup(->browsers) EmbeddedInContentDocument(false->false)
28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/BrowsingContext SetOwnerProcessId for 0x00000006 (0x00000000 -> 0x00000002)
28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/BrowsingContextSync Transaction::Apply(#6, local): CurrentInnerWindowId(0->11)
28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/BrowsingContextSync Transaction::Apply(#6, local): ExplicitActive(1->1) EmbedderInnerWindowId(10->10) UseGlobalHistory(true->true) FullscreenAllowedByOwner(true->true) EmbedderElementType(Some(browser)->Some(browser)) MessageManagerGroup(browsers->browsers) EmbeddedInContentDocument(false->false)
28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/BrowsingContextSync Transaction::Apply(#6, local): IsActiveBrowserWindowInternal(false->false)
28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/BrowsingContextSync Transaction::Apply(#6, local): EmbedderColorSchemes(???->???)
28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/BrowsingContextSync Transaction::Apply(#6, local): DisplayMode(0->0)
28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/BrowsingContextSync Transaction::Apply(#6, local): UserAgentOverride(->)
28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/BrowsingContextSync Transaction::Apply(#6, local): AllowJavascript(true->true)
28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/BrowsingContextSync Transaction::Apply(#6, local): ForceDesktopViewport(false->false)
28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/BrowsingContextSync Transaction::Apply(#6, local): ForceEnableTrackingProtection(false->true)
28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/BrowsingContextSync Transaction::Apply(#5, local): Loading(false->false)
28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/BrowsingContextSync Transaction::Apply(#5, local): IsActiveBrowserWindowInternal(false->false)
28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/BrowsingContextSync Transaction::Apply(#5, local): IsActiveBrowserWindowInternal(false->true)
28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/BrowsingContextSync Transaction::Apply(#6, local): IsActiveBrowserWindowInternal(false->true)
28836 28868 I Gecko   : [Parent 28836: Main Thread]: D/BrowsingContextSync Transaction::Apply(#6, local): CurrentLoadIdentifier(Nothing->Some(14))
29885 29904 I Gecko   : [Child 29885: Main Thread]: D/BrowsingContext Creating 0x00000006 from IPC (origin=0x00000000)

Maybe calling chain : content process killed -> BrowsingContext::Detach -> Canonical()->CanonicalDiscard(); -> DecreasePrivateCount(); -> Fire last-pb-context-exited event-> Flush all the cookies stored by private browsing contexts


The problem is that in GeckoView, 1 tab = 1 window , should we fire last-pb-context-exited in this situation?

Flags: needinfo?(nika)
See Also: → 1875757

I'm guessing that when a content process crashes or is killed by the OS on Android, we destroy the corresponding GeckoSession and then attempt to re-create it with SessionStore when the tab is re-loaded. Within Gecko proper, we use the count of private content browsing contexts to decide when to delete the private browsing session, so if all private browsing sessions are killed in the background, and then GeckoView tears down their corresponding BrowsingContext, we'll end up firing last-pb-context-exited and destroying the session.

I believe this doesn't come up for desktop, as IIRC a crashed tab on desktop still keeps the private BrowsingContext alive to load the tab crashed page into, and I don't believe we support discarding and then restoring all private browsing tabs (though if that is somehow possible perhaps it's possible to trigger the bug by discarding all pb tabs - not sure how you'd do that though as the pb window will have to be showing at least 1 tab).

Perhaps GeckoView needs to provide some form of additional API to allow an embedder to keep the private session alive even after all private BrowsingContexts have been destroyed. This would need to be done through the runtime EventDispatcher, and would likely be easiest to implement by calling the IncreasePrivateCount and DecreasePrivateCount methods defined in CanonicalBrowsingContext (https://searchfox.org/mozilla-central/rev/c130c69b7b863d5e28ab9524b65c27c7a9507c48/docshell/base/CanonicalBrowsingContext.cpp#81-117).

If an API like this is added, we'll need to be careful to not accidentally keep PB state around longer than expected due to a bug in the frontend.

Flags: needinfo?(nika)

Here's the new observation

STR 1.

  1. Open Private Mode
  2. Open a private tab "https://example.com"
  3. Open a private tab "https://setcookie.net" and set cookies
  4. Close "https://setcookie.net" and reopen it again (could do via "Undo button")
  5. Cookies still exist.

STR 2.

  1. Open Private Mode
  2. Open a private tab "https://setcookie.net" and set cookies
  3. Close "https://setcookie.net" and reopen it again (could do via "Undo button")
  4. Cookies do not exist.

The problem is related to how many enginesession remains, if 0 , the 'last-pb-context-exited' event emits and cookies drop.
So when low memory , all tabs' enginesession is closed , then cookie dropped.


However If we prevent 'last-pb-context-exited' event in Android , then another problem will occur : The "felt privacy" and "click private notification to close all" features will not work by design (If they mean to clear cookies and etc...) . They remove all tabs and close these tabs' enginesession to trigger 'last-pb-context-exited' to clear cookies.


I think "felt privacy" and "click private notification to close all" should not clear cookies and only exiting application should , but this doesn't following Desktop's behavior.
The key is that Firefox Android dropped enginesession when low memory , but desktop wouldn't (or wouldn't have similar behavior)

The phenomenon continues to occur:

Nightly
134.0a1 (Build #2016056007), hg-108d038388ff+
GV: 134.0a1-20241113215256
AS: 134.20241109050310

Priority and severity are set. Why is this bug still in "unconfirmed" status?

Duplicate of this bug: 1875757

The severity field for this bug is set to S4. However, the following bug duplicate has higher severity:

:Gela, could you consider increasing the severity of this bug to S3?

For more information, please visit BugBot documentation.

Flags: needinfo?(gmalekpour)
Severity: S4 → S3
Flags: needinfo?(gmalekpour)
Flags: needinfo?(c52w1h6sv)

Is it possible to prioritize this issue a little higher? Switching tabs or apps frequently is part of everyday life.

This is particularly annoying when it comes to sending one-time codes via text message or email. If you log out in the meantime, you cannot enter this code. Often, such codes then lose their validity, meaning that the process has to be restarted.

147.0a1 (Build #2016129151), fba782c1c5d53ab597689b6d712132e7e279c083
GV: 147.0a1-20251129212903
AS: 147.20251127050325
OS: Android 15
Flags: needinfo?(c52w1h6sv) → needinfo?(gmalekpour)
Assignee: nobody → rebecatudor273
Whiteboard: [fxdroid][group2]

I am able to reproduce this if I check No background processes

Flags: needinfo?(gmalekpour) → needinfo?(c52w1h6sv)
Flags: needinfo?(c52w1h6sv)

A few notes:

  • This can be a bit tricky to reproduce, but the most consistent way for me has been after I selected No background processes under the device setting.

  • This appears to only occur when I have one private tab open. I was not able to reproduce this with multiple private tabs. My theory here is that because Gecko’s private cookie jar lifetime is tied to whether there is any private browsing context remaining. With exactly one private tab, switching out of PBM can temporarily remove the last existing PB context; with two+ tabs, something usually keeps a PB context alive, so the “last PB context exited” cleanup never triggers.

  • I initially assumed this issue is caused by browser-state middleware (e.g., SuspendMiddleware, KillEngineSessionAction, UnlinkEngineSessionAction) suspending or killing private tabs’ engine sessions. I tested this by adding breakpoints and even commenting out session suspension/close calls and the cookies were still deleted. So this appears to be happening elsewhere and before the Suspend call.

The only ways I was able to reproduce this bug:

  • selecting No background processes. Having this option selected on device makes sense to reproduce the bug because when the app goes in background the app gets killed and data it's not saved for private mode. It's expected even when we don't put the app in background and we just go from private mode to normal mode because behind the scenes the app is restarted.
  • Having more apps in background. After I open Firefox I open other apps and the those new apps consumes the device resources, Firefox will be killed. So when I come back to Firefox the app was restarted and the data was lost which it's expected. So in this case, the bug happens depending on the device's resources and how the system manage them.

Otherwise following the steps described by reporter and other comments I was unable to reproduce this bug.
I tested multiple times:

  • changing modes (private/normal).
  • putting the app in background and going to another app for awhile and coming back.
    Could QA test this bug as well?
Flags: qe-verify+

Rebeca, I was not able to reproduce this issue.
I've opened one tab in private mode, signed in (it was gooogle.com, or istagram.com, or wikipedia.org), sent the app in the background, and opened other apps. Switched from other tabs to Firefox for Android, I was still signed in.

Tested on a Samsung Galaxy S24 (Android 16), and on a Xiaomi Poco X7 (Android 16), on Firefox for Android Nightly 149.0a1, and on 147.0.3.

Flags: qe-verify+

Thanks Mira, did you check No background processes in your device's settings?

Flags: needinfo?(mlobontiuroman)

Hi, Gela,
The "Background process limit" was set to "Standard limit".
As soon as I set it to "No background proccesses", I was signed out from private browsing.

Flags: needinfo?(mlobontiuroman) → needinfo?(gmalekpour)
Flags: needinfo?(gmalekpour)
Assignee: rebecatudor273 → nobody
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: