Firebase’s Password Reset is Insecure. Here’s How to Fix It.
Firebase Auth’s default password reset app is insecure, as it allows users to enter insecure passwords. My project provides a drop-in replacement.
My previous blog described how Firebase’s password reset system is insecure. This blog introduces a new open-source project which acts as a drop-in replacement for the insecure system.
The problem applies to apps using email/password authentication in Firebase Auth. When a user asks to reset their password, they are by default sent to this mini-app:
As you can see, there is next to no password security. Its only stipulation is that passwords must be 6 or more characters long. And so users can choose really ordinary passwords like ‘aaaaaa’ or ‘123456’.
Over time, therefore, users will migrate to less and less secure passwords with increasing use of the password reset feature.
The easy solution
The SafeFirebasePasswordReset repo is designed as a drop-in replacement for Firebase’s default, insecure password reset mini-app. It looks like this:
Note here how it provides warnings when common passwords are used, or passwords that would be very easy to guess. It also gives the user hints as to how to improve their entry.
The repo is open-source, easily customisable, and free for any use (MIT license).
How to use SafeFirebasePasswordReset
We’re going to build the mini-app from the code, serve it using Firebase Hosting, then update the email template to point to the new location.
For this, you will have the following installed:
- Git
- NodeJS
- Firebase CLI (once installed, open a command prompt window and type
firebase login
).
From a command prompt, start by cloning the repo: git clone https://github.com/tdcolvin/SafeFirebasePasswordReset.git
.
Configuring and building the app
Then cd
into the directory created by the clone: cd SafeFirebasePasswordReset
. From there, grab the required node modules by running npm i
. Once completed you will have a node_modules
directory.
You will need your Firebase config object. To get this, navigate to your Firebase console, click the cog icon, click Project Settings, click Add App in the General tab, click the Web icon (labelled </>), enter Password Reset as the app name, and press Register app. You will get a screen as below:
Copy the text in the red box into the relevant place in the src/firebaseConfig.ts
file. Now SafeFirebasePasswordReset is set up for your project.
Finally, build the mini-app by running npm run build
. This should end as follows:
Once that is complete, and you’ve not hit any errors (look for the green “Compiled successfully” line), you will have a build directory in your project with the following contents:
These are the files you need to serve the mini-app, and we’re going to serve them via Firebase Hosting.
Firebase Hosting: Making the mini-app available on the web
Firebase Hosting is a good choice for hosting apps. It’s no-frills but nicely integrated with Firebase itself, and has a generous free tier. But you can use almost any other hosting platform here; there’s nothing that Firebase Hosting does that’s special in our case.
If you’re using it in your project already then you should create a new site for this app. Otherwise, open Firebase Hosting from your project’s Firebase console and you will be walked through how to get started:
When you click the Get started button you’ll be presented with a step-by-step guide; just keep pressing Next and finally Continue to the console.
From a terminal window, cd
to your mini-app’s directory, then type firebase init
.
Navigate down (arrow keys) to Hosting, press space to select it, then enter to continue.
- Select your login on the next question.
- Select Use an existing project
- Select your Firebase project
- For What do you want to use as your public directory?, type build and press enter. (We want to use the build directory we made earlier).
- For Configure as a single page app? the answer is yes. Type y and press enter
- For Set up automatic builds and deploys with GitHub?, choose No.
Here is the confirmation showing those options:
We now have Firebase Hosting configured for our app, woohoo!
The only remaining step is to upload the app so that it’s available on the web. Type firebase deploy
and press enter. You will see the following:
Note the hosting URL at the bottom — you’ll need this later.
Sending users to the new app
Finally, we need to update Firebase’s password reset email to point users to the new address.
In your Firebase Console, choose Authentication and then click the Templates tab. Press the edit icon (the pencil top right) and click Customise action URL.
Here, enter the hosting URL obtained above into the box plus /#. So if your hosting URL is https://your-firebase-project.web.app
then enter https://your-firebase-project.web.app/#
(Why the #? Because it’s slightly more secure. That way, the user’s browser won’t send their password reset key across the internet when they visit the page).
Save, and you’re done.
If you have any problems please open an issue on the GitHub repository and I will do my best to respond. As this is a brand new repo, any and all feedback is very gratefully received, and all contributions are even more so.
Tom Colvin is an Android and security specialist. He is available as a freelancer. He is the co-founder of the app development specialists Apptaura, where he runs the development team.
Coda 1: how SafeFirebasePasswordReset measures password strength
SafeFirebasePasswordReset
uses the zxcvbn library which has an interesting — and in my view much more secure — approach to password strength estimation. It favors guessability over composition, a strategy approved by OWASP.
For example, take the common password “password”. If you only force users to use a mix of uppercase, lowercase, numbers, and symbols then “P@ssw0rd” would pass the test. Yet, to a password cracker, that’s only a tiny bit more secure than the original. By contrast, zxcvbn estimates how long a password would take to crack regardless of its composition.
Coda 2: action URLs
Firebase doesn’t allow you to change the action URL for just the password reset email. The same URL appears in emails sent for other reasons, such as address verification and MFA enrolment.
This is frustrating!
SafeFirebasePasswordReset
fixes this by simply redirecting the default app in cases other than password reset.
Coda 3: upcoming changes in Firebase password policy
In future, it appears you will be able to configure Firebase Auth to force passwords to be a certain length, or contain certain types of characters. This isn’t yet generally available.
In any case, it only applies to Firebase Auth with Identity Platform (which has significant cost impacts over the default Firebase Auth). Even when rolled out, that change wouldn’t prevent the use of passwords like Passw0rd!
which are hardly any more secure than the dictionary words they are based on. But it’s a good step forward for Google, and hopefully, one-day SafeFirebasePasswordReset
will no longer be needed.