How to block firestore REST API access - firebase

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.

Related

How to Connect Zapier to Firebase API with Oath2

I'm creating a Zapier Partner integration into my Firestore app.
I want Zapier to send data to Firestore.
It could go through a Firebase API.
Firestore data is structured relative to a users Id. I.e. /users/{userId}
What is the correct set of steps to ensure that a request from Zapier to store data in the API is for the correct user?
I assumed:
I need to add a OAuth 2.0 Client to my API section in Google Cloud (which gives me a ClientId and secret)
I need to unpack the token coming into the API to ensure that it relates to a valid user
Honestly OAuth2 plus the disparate technologies make it a bit fuzzy to see a clear path to implementation.
Many thanks.

Pass context value into firestore document add/set/update from Admin SDK

I am looking to use the https.onCall to accept some input from a user (such as data about another user). I'd then like to do some advanced processing on that data including retrieving sensitive data from other entries on my firestore that should not be exposed. Depending on the outcome of that analysis, I will update other locations in the database. However, I am concerned about the security of the original call and its source. I know that I have the context parameter on the onCall to verify the source was logged in, but I'd like to apply security rules to the final write based on the context.auth provided to the cloud function.
The security rules are straight forward for normal database operations but not if I'm doing an operation (seeded by a normal user) routed through the Admin SDK.
Thoughts?
but I'd like to apply security rules to the final write based on the context.auth provided to the cloud function
As you are aware that you can identify which user made a call to functions as well as that Admin SDK has super-access to database, the general flow should be to write functions in a way that they only edit documents that should be editable by the user.
If you had still like to narrow down access, you can do that for firebase database by passing databaseAuthVariableOverride when initializing admin app.
Read more on authenticating with limited privileges
When you use the admin SDK, or any of the server SDKs, it always bypasses all security rules. Rules only apply to access coming directly from web and mobile clients using the client SDKs.
If you need to apply some sort or restricts to data written from your backend, you will need to code that into the logic of your backend code. Security rules will be of no help.

Is it safe to send the access token in the URL? Firebase Realtime Database REST API

I am using Firebase realtime database rest API on the client-side. I noticed that you need to send the access token on the URL and this info is exposed on the request.
Is this a secure way of using the REST API? Is there another more secure way of accomplishing this?
Here is the documentation: https://firebase.google.com/docs/reference/rest/database#section-param-auth
When you see "https" at the front of the URL used for the API, that means the data is encrypted and can't be intercepted. So passing data along with the query should not pose a security problem in terms of someone gaining access to your key.
However, if you ship a client app that contains the key, you are basically giving it away to anyone who has your app, as it's always possible for someone to reverse engineer your app and gain access to all data inside it. To avoid that, you should be using Firebase Authentication and security rules to determine who can access the data in your database.

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.

Is Firebase really Secure?

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.

Resources