Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auth with Redirect Flow does not work with the most recent versions of Firefox #6443

Closed
matei-radu opened this issue Jul 18, 2022 · 4 comments

Comments

@matei-radu
Copy link

Describe your environment

  • Operating System version: Arch Linux, kernel 5.18.12, also tested with macOS 12.4
  • Browser version: Firefox 102
  • Firebase SDK version: 9.3.0, also tested 9.9.0
  • Firebase Product: auth

Describe the problem

Recently, Mozilla started rolling out their "Total Cookie Protection" feature enabled by default with Firefox (see blog post: https://blog.mozilla.org/en/products/firefox/firefox-rolls-out-total-cookie-protection-by-default-to-all-users-worldwide/). Firebase Auth with the Redirect Flow seems to rely on some cookies to complete the authentication, and these cookies are now partitioned (aka isolated) by this "Total Cookie Protection", preventing the Firebase JS SDK from completing the process.

Once the user is redirected back to the application, both onAuthStateChanged and getRedirectResult will invoke their callbacks with null instead of a User object. A warning message can also be seen in the console, like the following:

cookie_partitioning

The [Learn More] points to this: https://developer.mozilla.org/en-US/docs/Web/Privacy/Storage_Access_Policy/Errors/CookiePartitionedForeign.

Manually disabling this Firefox storage partitioning feature allows the Redirect Flow to function properly.

Steps to reproduce:

  1. Set up a basic frontend application with Firebase Auth using the Redirect Flow.
  2. Set up a fresh install of Firefox with out-of-the-box settings. In my case I had version 102.
  3. Check that the cookie partitioning feature is enabled. To do so, navigate to about:config in the URL bar, the search for network.cookie.cookieBehavior. If the value is set to 5 then cookie partitioning is enabled. Values 4 and 0 differ in some way but in both cases partitioning is not enabled.
  4. Attempt to authenticate, it should not work as both onAuthStateChanged and getRedirectResult will invoke their callbacks with null instead of a User object after you are redirected back to the application.
  5. Manually disable the cookie partitioning following the instructions of point 3, so set network.cookie.cookieBehavior to either 4 or 0.
  6. Attempt to authenticate again, this time it should work.
@google-oss-bot
Copy link
Contributor

I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.

@sam-gc
Copy link
Contributor

sam-gc commented Jul 18, 2022

Hi @matei-radu, thanks for opening this issue. Firebase Auth does not use cookies for signInWithPopup() and signInWithRedirect(), but it does use your Firebase Hosting domain (that firebaseapp.com URL) to handle OAuth redirects. The issue is that the SDK also opens an iframe to that domain in order to read the OAuth response from storage. If that iframe is cross-origin (as it is in this case), it appears Firefox is blocking that iframe's access to storage.

There are three ways to mitigate this for the moment, listed below from easiest to most complicated:

  1. The easiest is to use signInWithPopup() instead of signInWithRedirect(). The former does not rely on browser storage.
  2. If you are using Firebase Hosting, update the authDomain field in your Firebase Config to match the domain your app runs on. This will ensure that the iframe being opened is not cross-origin. To do this, you'll need to add `https://your-domain/__/auth/handler to the list of authorized redirect URIs for your OAuth app. How you do this depends on the provider. For Google, for example, you'd go to the Cloud Console's Credentials page, click into the "Web client" under the "OAuth 2.0 Client IDs" heading, and add that URI to the "Authorized redirect URIs" section. For the other providers, you can follow the "Before you begin" sections, but update the URL as described.
  3. You can sign in to the OAuth provider manually, then simply authenticate with Firebase at the end using signInWithCredential(). For example, with Google: https://firebase.google.com/docs/auth/web/google-signin#advanced:-handle-the-sign-in-flow-manually

@sam-gc sam-gc removed the v9 label Jul 18, 2022
@matei-radu
Copy link
Author

Thanks for clarifying @sam-gc. I got so lost in the Mozilla material for their feature that I didn't realize the blocked resource is actually an iframe. They use the word cookie a lot for this.

I was already considering switching to signInWithPopup() but I want have a shot at your second option first.

I assume then that this, with my current setup, is an expected behavior, right? In that case I think we can close the issue.

@matei-radu
Copy link
Author

In the end I went with the signInWithPopup() solution, all good now.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants