Can someone create an account in my app even if I don’t have signup functionality?
Can someone create an account in your Firebase app without you knowing about it? Even if you don’t have a signup form, is there a way to go into devtools get my credentials and use them to create an account?
These are all common questions that we all ask ourselves when we’re getting to know Firebase, and the reality is that yes, by default, they can.
That does not mean we can’t do something about it, on the contrary, Firebase provides a different set of tools so that you can protect your application.
Authorized Auth Domains
For security reasons, to be able to use Phone Number, Social, or 3rd party authentication (all of the ones that require redirects or popups) the domains you’ll use need to be authorized.
So, one of the first things we should do before deploying our app is ensuring that only the domain we’re going to use is in the authorized domain’s list.
For that, navigate to the Firebase Console, open your app, and go to the authentication tab. Inside the auth tab, you’ll find a couple of options, go to Sign-in method as shown in the image below.
Click the Add domain button, and add the domain you’ll use to serve the app.
Also, make sure to take out any domain that there that you won’t use, for example, localhost
, we don’t want someone
getting your Firebase credentials and using them to create a Firebase app and serve it from localhost
to create users
in your Firebase project.
Lock your API key
In the step above, we added our domain as an authorized domain to perform OAuth operations, but what about email authentication? For someone with enough experience, it’s simple to load your app and use chrome dev tools to find your Firebase credentials, use them in their project locally, and add users to your Firebase app.
No need to panic, you can lock your API Key too, and that way, it can only be used from your domain.
For this, you need to go to the Google Cloud Credentials page: https://console.developers.google.com/apis/credentials.
When you’re there, locate your project, and you should see something like the image below.
We’re focusing on your API Key, it’s the one from your Firebase Credentials:
firebase: {
apiKey: "This is your API Key",
authDomain: "",
databaseURL: "",
projectId: "",
storageBucket: "",
messagingSenderId: "",
appId: ""
}
You can spot it in the Credentials dashboard because it’s usually called “Browser Key (autogenerated by Firebase)". Click the edit icon and it will take you to a page specifically for that API Key.
Once on that page, you can edit it, change its name, or add application and API restrictions, let’s start with application restrictions.
First, let’s understand what application restrictions are, are restrictions we put on our API key saying, you will only work in this application.
For example, we can lock our API Key so that in only does query to Firebase from our domain, or if we’re using a native app, we can lock it so that it only receives queries from that application’s package.
That way, if I get your credentials and load them into my environment, I will get an error whenever I try to access any of your Firebase services. Error image below showing a 403 permission error:
To restrict our API to be used only from certain domains, go down to the Application restrictions tab and select the option: HTTP referrers (web sites).
Once you do, a new space will open the app and you’ll see a button that says ADD AN ITEM, click it and add your domain name there.
You need to be careful with how you add domains, if you make a mistake here, you can block your application from accessing Firebase.
There are 3 use-cases we should account for:
First, to give access to all the routes on our domain to have access to Firebase, we do that by adding our domain and our domain with a wild card, like this:
https://jsmobiledev.com
https://jsmobiledev.com/*
If you also serve unprotected content via http (you shouldn’t) you need to add it there, like this:
https://jsmobiledev.com
https://jsmobiledev.com/*
http://jsmobiledev.com
http://jsmobiledev.com/*
Also, if don’t have a redirect from www and serve content from there you need to add it too, in the end, it would look something like this:
https://jsmobiledev.com
https://jsmobiledev.com/*
http://jsmobiledev.com
http://jsmobiledev.com/*
https://www.jsmobiledev.com
https://www.jsmobiledev.com/*
http://www.jsmobiledev.com
http://www.jsmobiledev.com/*
I recommend 1) you only use https for security reasons, and 2) set up a redirect for www so that you don’t have to take it into account.
Our second use-case is when we have a subdomain in use, let’s say we have our website running and the application runs from an app. subdomain, we need to add that subdomain there like this:
https://app.jsmobiledev.com
https://app.jsmobiledev.com/*
And our third use-case would be if instead of one, we have multiple subdomains accessing the app, for that, we can add wildcards like this:
https://*.jsmobiledev.com
https://*.jsmobiledev.com/*
So, if in the end, you want to allow your main domain, and any subdomain, your domain list should look like this:
https://jsmobiledev.com
https://jsmobiledev.com/*
https://*.jsmobiledev.com
https://*.jsmobiledev.com/*
Restrict Your API Key
After you’re done setting up application restrictions, it is a good idea to also set up API restrictions. API restrictions tell Firebase which Google APIs your API can access.
It’s a good idea, because if your API is compromised, and someone manages to spoof a request from your domain, then we have an extra layer of security that says, ok, this API key can only access Firebase Auth, and Firestore, nothing else.
For that, navigate to the end of the page where it says API restrictions and select the Restrict key option. You’ll see a select input box there, feel free to select all the Google API’s you want access to.
This will work for more than authentication, you’re also locking Firestore access and more, so make sure that you do this for your production app and that before doing it, you have set up the Firebase Emulator, so that you can develop your app locally unrestricted.