In my frontend react project I exported a firebase instance :
firebaseApp.js
import * as firebase from "firebase/app";
import "firebase/auth";
import "firebase/storage";
export default firebase.initializeApp({
... <props>
});
Whenever I need to use firebase in my project, I do this :
import firebaseApp from "../firebase/firebaseApp";
[...]
await firebaseApp.auth().signInWithEmailAndPassword(email, password)
Knowing that Javascript is put client side as this is a frontend project, is there a way for people to open the browser console, access my instance of firebase and call for example :
firebaseApp.auth().createUserWithEmailAndPassword(email, password);
which will result in creating users without backend authorization, and allow bots to create users ?
Iow, can someone access a module instance from the browser and play with it ?
It is indeed possible to take the configuration data from your existing web app, and use that to call the API in another way than your code does. And that does indeed mean that users can create accounts outside of your app.
Firebase makes a clear split between authentication (the users prove who they are) and authorization (the is is granted access to data). Firebase Authentication takes care of the former, while you use security rules (see below) or server-side code to take care of the latter.
For this reason you should never trust that the code that accesses your project is the same code that you wrote. So instead of assuming it's your application, think of what you want a user (no matter what code they use) to be able to do.
For example, if you're using one of the Firebase's databases (the Realtime Database or Cloud Firestore), you'd use their built-in server-side security rules to ensure any user can only access the data they're authorized for. In that case it doesn't matter if the user used your code, or wrote their own code: they'll have to follow those server-side security rules.
This is a common concern, so I recommend also reading some of these questions and answers:
Is it safe to expose Firebase apiKey to the public?
Restrict access to Firebase storage so only my app can access it
Locking down Firebase DB access to specific apps
Related
Summary
I need to create an application where the user will subscribe to a plan that will give him a consumption of requests to the backend.
Backend: I will use nodejs and express to create the backend
Frontend: I will use reactjs to create the frontend. I will create the admin panel for user control you account.
Detail
I need to create a plugin for Wordpress that will consume these requests from the user's account. As I've never worked with this type of structure, I don't know how to guarantee that these plugins are the client's own and not someone who took his credentials and is spending his plan.
I took a look at RSA encrypt to make a data signature, but I still don't understand the best way to create this application.
I also saw about JWT but the plugin in wordpress would not have the account credentials to use JWT as login, and usually plugins and REST API using public key and secret key or api key.
Another use would be embedding a form on another site or using the REST API.
I'm building a bot hosted on Azure and using firebase for cloud functions (ie proactive messaging, collating data etc.) and for cloud firestore db.
Sorry as I'm a bit new to security and please feel free to just link to any useful resources on the below.
Within my bot code I'm using the admin SDK to access firebase. The bot will have no created users. Firestore rules therefore block read and write access to everyone (as admin SDK still has full access).
I have a couple of questions about security:
Is using the admin SDK in this manner (on the bot side) fine? It looks a bit mixed on the firebase documentation - ie https://firebase.googleblog.com/2019/03/firebase-security-rules-admin-sdk-tips.html mentions only using these in trusted environments, which I think the bot should be?
Secondly I am trying to send messages from cloud functions to the bot itself. This will just be a post with no sensitive data attached but I would like to authenticate this on the bot side to check it is from the backend. Is there a way to use firebase to do this (ie authenticating on client?). How else can I do this? I've been a bit confused reading about JWTs and encoding etc.
Thanks
Is using the admin SDK in this manner (on the bot side) fine?
It's totally fine. You don't have security rules there but Cloud functions (or servers) are secure environments so no one can reverse engineer that. You should validate the incoming data yourself. If I assume you are using Discord.JS, then you can just read ID of author and authorize the user:
const {id} = message.author
// use this ID as an identifier
You don't have to worry about the ID being false as it's not being passed by any client. Just make sure you fetch resources of that specific user only.
I am trying to send messages from cloud functions to the bot itself. I would like to authenticate this on the bot side to check it is from the backend
You don't need to validate that. Anyone can send message through your bot only if they get your bot's token which is a secret on server/cloud function. You must make sure only you have it.
I'm using Firestore as an MVP DB for an API we've got hosted on Heroku. The API doesn't use any authentication outside the OAuth provided by platforms like Slack and Google, and we're also not using any of Firebase's authentication
I'd like to change our security rules away from the insecure
allow read, write: if true; but I'm unsure how to write these rules in my context given most of the docs show security rules using Firebase auth or collection visibility
So, a couple questions:
Is it secure "enough" that I'm using the Firebase admin SDK on the Heroku server to access Firestore, but that my security rules basically allow access to anyone?
If not, How can I write rules that allow access only to a specific Heroku API endpoint?
Alternatively, are there better practices I should use to secure the data?
Thanks so much
The Admin SDK to access the database with special administrative privileges, and bypasses the security rules. So if you only access the database through the Admin SDK, you can lock the database for access by regular users with:
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
}
}
For an MVP, I think allow read: if True is not really a problem, depending the data you make available. However, on write, you can easily implement a rule with the incoming data, like that for example :
allow write: if request.resource.data.securityKey === 'custom key shared between firebase and heroku'
A better option would be to use the auth module firebase.auth().signInWithEmailAndPassword(email, password), store an email and password in the env variable of your heroku app and auth from there.
Without cloud functions, it appeared that it required a app server to securely limit signups for a firebase app by email domain according to this old question: How do I lock down Firebase Database to any user from a specific (email) domain?
The goal is to allow only signups from a specific domain or set of domains using google authentication and/or other auth providers.
Now that we have firebase cloud functions how can this be accomplished without an app server?
From the Introduction section of the Firebase Functions page:
Firebase SDK for Cloud Functions integrates the Firebase platform by letting you write code that responds to events and invokes functionality exposed by other Firebase features.
The keyword being responds. The Firebase functions are only meant to react, not prevent, so to speak.
If you picture the scenario of a user signing up, your functions would only fire after a user has been created (functions.auth.user().onCreate). By that measure, if you were to do this with Firebase Functions then you would have to delete the user after it was created, making your client side logic really messy.
The rules that Josep directed you towards is the correct solution. They will actively prevent any signups from a given domain.
I hope this clarifies a bit, even though it might not have been the answer you were looking for. :)
Firebase provides database back-end so that developers can focus on the client side code.
So if someone takes my firebase uri (for example, https://firebaseinstance.firebaseio.com) then develop on it locally.
Then, would they be able to create another app off my Firebase instance, signup and authenticate themselves to read all data of my Firebase app?
#Frank van Puffelen,
You mentioned the phishing attack. There actually is a way to secure for that.
If you login to your googleAPIs API Manager console, you have an option to lock down which HTTP referrer your app will accept request from.
visit https://console.developers.google.com/apis
Go to your firebase project
Go to credentials
Under API keys, select the Browser key associated with your firebase project (should have the same key as the API key you use to initialize your firebase app.)
Under "Accept requests from these HTTP referrers (web sites), simply add the URL of your app.
This should only allow the whitelisted domain to use your app.
This is also described here in the firebase launch-checklist here: https://firebase.google.com/support/guides/launch-checklist
Perhaps the firebase documentation could make this more visible or automatically lock down the domain by default and require users to allow access?
The fact that someone knows your URL is not a security risk.
For example: I have no problem telling you that my bank hosts its web site at bankofamerica.com and it speaks the HTTP protocol there. Unless you also know the credentials I use to access that site, knowing the URL doesn't do you any good.
To secure your data, your database should be protected with:
validation rules that ensure all data adheres to a structure that you want
authorization rules to ensure that each bit of data can only be read and modified by the authorized users
This is all covered in the Firebase documentation on Security & Rules, which I highly recommend.
With these security rules in place, the only way somebody else's app can access the data in your database is if they copy the functionality of your application, have the users sign in to their app instead of yours and sign in/read from/write to your database; essentially a phishing attack. In that case there is no security problem in the database, although it's probably time to get some authorities involved.
Update May 2021: Thanks to the new feature called Firebase App Check, it is now actually possible to limit access to your Realtime Database to only those coming from iOS, Android and Web apps that are registered in your Firebase project.
You'll typically want to combine this with the user authentication based security described above, so that you have another shield against abusive users that do use your app.
By combining App Check with security rules you have both broad protection against abuse, and fine gained control over what data each user can access.
Regarding the Auth white-listing for mobile apps, where the domain name is not applicable, Firebase has
SHA1 fingerprint for Android apps and
App Store ID and Bundle ID and Team ID (if necessary) for your iOS apps
which you will have to configure in the Firebase console.
With this protection, since validation is not just if someone has a valid API key, Auth domain, etc, but also, is it coming from our authorized apps and domain name/HTTP referrer in case of Web.
That said, we don't have to worry if these API keys and other connection params are exposed to others.
For more info, https://firebase.google.com/support/guides/launch-checklist