Is Firebase really Secure? - firebase

I'm looking into using Firebase for a project that's otherwise a static site with js. Is it possible to secure the connection to the database in a static site? Wouldn't all security rules, the end point url, etc all be exposed in the js code letting the user make any requests they want (good or bad).

The short answer is yes: by authenticating your users and writing security rules, you can fully restrict read / write access to your Firebase data.
In a nutshell, Firebase security is enforced by server-side rules, that you author, and govern read or write access to given paths in your Firebase data tree.
Firebase security rules are JavaScript-like expressions: easy-to-write expressions that have access to the credentials for the connection, and the view of the Firebase data tree as it exists, along with pending changes on write.
In most cases, your client-side logic, templates, assets, etc. will be static and public. What you're really looking to secure is user and application data, and this is where Firebase Authentication (whether using custom Firebase authentication tokens or Firebase Simple Login) comes in. Firebase Authentication is essentially token generation - taking confirmed, identifiable user data and passing it securely to Firebase so that it cannot be spoofed. This confirmed credential data is then made available in your security rules.
Check out https://stackoverflow.com/a/20842986/879295 for an example, and the Firebase Security Quickstart Video for a great overview / starting point.

Related

End user authentication in Google Cloud Storage

in the last few days I have looked into Google Cloud Storage Buckets. I would like to know how to authenticate and authorize users when accessing data, preferably without the use of a backend.
Context: I have an app with the following requirements: Authenticated end users should be able to upload data to a (or their) bucket, with the default read access being scope to the user. At any point, the owner of the bucket should allow the bucket contents to be available to the public (publish bucket contents, read only).
End users are currently being authenticated with JWTs on the browser.
I have looked at the different ways of controlling access to Storage Buckets.
To my understanding:
IAM is unsuitable as it is meant for Google Accounts and should be used within the company, not to authenticate end users (clients)
ACLs are seemingly not recommended and are described as a legacy way meant for interoperability with S3
Signed URLs are "ok" for uploads, but I would rather have an actually authenticated way of uploading.
What's totally unclear to me: what access control method can be used to authenticate my end users (pref. with JWTs) especially for reading data?
This seems like an issue everyone should face, but I can't seem to find good info? On a side note: I am aware that Firebase exists for this reason, I just want to know how to tackle this on GCP.
There is no other solution than signed URL and a backend (I know that breaks your requirement) that check the authentication and generate that signedURL (on only the relevant/authorized files)
When implementing this purely in GCP, you'll typically end up implementing your own auth solution for your clients, and then your own authorization model in your server-side code.
If you want to not implement this yourself, using Firebase for your Cloud Storage access would be the way to go. This implements client-side authentication and server-side security rules to control access.

Secure app using firebase auth to stop malicious use of the key which is on the client

I was wondering how to to secure firebase auth. I plan on using firebase JUST for user authentication (not using firestore or realtime db). Since the API key is exposed on the client, my fear is that a malicious user can find the key and start using it inappropriately. So far I've done the following to try to improve security:
Limit key use to a specific domain
Restrict the key to only be able to use "Identity Toolkit API"
Is there anything else I should do here?
My application should be the only one able to use my credentials to access the Firebase API.
For any app where you access a cloud based API directly from within the client-side application code, that is going to be a myth. The closest you can get within Firebase these days is with App Check, but that isn't available for Authentication calls at the moment.
Part of the reason for this is that the authentication API is quite well protected on its own already, and most abuse will actually not affect you as a developer very much. E.g. (ignoring phone auth) there is no charge for account creation, sign in, and any other operations.
I highly recommend checking:
Is it safe to expose Firebase apiKey to the public?
The documentation on API keys in Firebase.
The documentation on Firebase's security rules, which is how you can protect the Firestore and Realtime databases, and files in Cloud Storage.
The documentation on Firebase App Check, which reduces abuse for Realtime Database, Cloud Storage, Cloud Functions, and Firestore at the moment.
More of these previous questions on allowing only you app to access Firebase

How to block firestore REST API access

I have a flutter app and use firebase auth and firestore. The data in firestore is only read and written from within the app.
I just realized, that every authorized user can access his data in firestore via the REST apis, if he has a correct auth token (e.g. from the AUTH rest api) and the API_KEY. As I understand, the API_KEY is not private.
So, even if I set up my security rules correctly, so that a user can only read and write his data, he could still access and change the data via the REST API. This could break my data model, as the data has to be structured in a special way.
Is there any way to allow access to firestore only from within the app and block it from REST calls?
Why are firebase API keys default unrestricted?
Should I limit the key to be used only by the Android APP like described here?
You should be validating the data requests within Security Rules to ensure that your data structure is being adhered to in all cases.
https://firebase.google.com/docs/rules/data-validation
as for the Rest API, it is not possible to outwardly block or deny it as it is built into GCP's core as part of the public API, however, you may be interested in App Check which can deny requests from outside your Android/iOS/Web app
https://firebase.google.com/docs/app-check
it's in early Beta and can help with unsolicited abuse to the mentioned platforms.

Firebase security rules, How to authenticate client app, not the users?

As I understand firebase security rules are for authenticating different types of users and provide authorization based on that, but what if my application doesn't need users to register at all? What if I just need to authenticate the application, not the users? What I mean by that is, I need to assure that particular firebase products are only accessed through an given application.
What I currently do to achieve that is, just make the security rules public assuming that the specific firebase sdk does the authentication stuff, but when I do that, I get the weird warning from the firebase console that security rules shouldn't be public. What am I doing wrong?
Another question, shouldn't we authenticate any application trying to access the firebase products even before starting the user authentication?
I also would like to learn how this is done generally (best practices) when developing serverless applications with firebase/google cloud platform products.
Firebase security rules don't support authenticating apps, only users. Authentication of an app would be pretty easy to simulate by an attacker, as all you would need is the secret compiled into the app in order to fool the rule. Even if you obfuscate the secret data, it's still just public data, and someone will figure out how to use it.
Once you ship an app to the world, you should consider everything in it to be public information, no matter how hard you might think it would be to extract that information (it's not that hard, really).

Can somebody get Firebase credentials from my apk and use them?

Can somebody else get the Firebase credentials from my APK and use them? Is this prevented by adding the SHA-1 keys for Android?
If it is prevented, what do I need security rules for since only code from my app with my SHA-1 can manipulate database at all?
If it is not prevented, can somebody else use my Firebase database as long as his requests fit the security rules? (Write 2nd client, which actually cannot do bad things but should not be allowed at all.)
Im not sure how I should think about security rules:
A) Protecting data against access and manipulation from bad guys + B?
B) Just a set of rules to keep data in a certain state and prevent my software from doing invalid database request?
A Firebase Database can be accessed via the REST API, or any of the client libraries. The decision about whether a client can or can't do something is entirely based on the rules.
You can even just access the Database URL in a web browser and see a JSON response by putting .json on the end, e.g. https://[YOUR_PROJECT_ID].firebaseio.com/.json
So the answer is definitely B! The default rules in a new Firebase project are that read and write to the database require auth, but you can configure them to provide whatever levels of protection you need.
Take a look at the Database Rules quickstart to see what you can do!
We don't ship the Realtime Database secret (or any other "secret" material) in the json file that gets baked into your app. That file simply contains resource identifiers that allow us to know which resources (database, storage bucket, analytics, etc.) to properly authenticate to (we use Firebase Authentication for these purposes), and we handle server side authorization to ensure that users are properly logged in.
If you are authorizing your requests properly (using Firebase Realtime Database Rules, for instance), your data is secure!
I'd recommend watching The Key to Firebase Security, one of our I/O talks, which talks in greater detail about how this works.
firebaser here
Thanks to the new feature called Firebase App Check, it is now actually possible to limit calls 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 that Mike and Ian describe in their answers, so that you have another shield against abusive users that do use your app.

Resources