It looks like Firebase, when they moved from the v2 to v3.x SDKs (and now into v4), decided to remove the option for automatic session expiration in favor of the always-authenticated model.
- Firebase 3.x - Token / Session Expiration
- https://groups.google.com/forum/#!topic/firebase-talk/uYMlQny1Jb4
This is a nice feature to offer, but from a cybersecurity perspective, I see some problems as this is the only option for the Firebase SDKs with Firebase-generated tokens such as email and password authentication (some of which are explained well in the linked google group discussion).
The commonly-provided suggestion to call user.signOut()
on page exit has some holes. Namely, if the client crashes, then this code is never executed and therefore the strategy falls apart. The "sign out on page load" suggestion also has holes in it:
- Forces all users to log in every time the page loads/reloads (not the goal)
- As Firebase pushes most everything to the client, there is nothing stopping someone for creating a script that attempts to access a targeted Firebase without having the
user.signOut()
I'm looking for a strategy that does a better job, from a cybersecurity perspective, that allows a user to opt in to the "always-authenticated" strategy if he/she so chooses, rather than it being the default (i.e. with a "Remember Me" button).
One strategy I came up with is as follows:
- User signs in
- Get the generated JWT for that session and write it to Firebase
- If the user didn't select "remember me" on sign in, set up an onDisconnect handler that clears the token from the list of that users tokens
- In Firebase security rules, ensure that the JWT for the user making the request is in the list of tokens for that user
This feels more secure because the onDisconnect
method will still execute even if the browser crashes. But, the JWT is not available as a Firebase rules variable (only the contents of the token)!
In light of these issues/flawed approaches, how can I invalidate a session after the browser closes/crashes (or even after a pre-determined period of time) with a Firebase-generated token?