How to Secure Firebase Access when App does not use Firebase Authentication - firebase

I'm dealing with an Angular app that authenticates users through a third party system.
I'm trying to figure out how to best secure the Firebase instance, which leverages Firestore and storage buckets.
I'm new to Firebase and when I look at the documentation I see security rules that look like this.
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.auth != null;
}
}
}
I can add authentication, is that's the best path forward. It seems redundant since they've already been authenticated by the other system.
On the other hand, the authentication provider is not currently supported as a Firebase authentication provider.
Is there a simpler way to limit access to Firestore and the storage buckets that doing Firebase Authentication?

The idiomatic approach is to implement a custom sign-in provider. That essentially puts your authentication data into the request.auth variable.

Related

How do we secure a Firebase Firestore without using Firestore Authentication? Or is it a must?

At this moment we have 1 Firebase Function running that connects to a Firestore database instance. It correctly connects to the Firestore database using the rules below, however this is insecure.
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if true;
}
}
}
It is however unknown to me how we should secure this if we don't have Users in our application. It is not multitenant. We just do HTTP calls to the function and it saves something in the database.
To build user-based and role-based access systems that keep your users' data safe, use Firebase Authentication with Firebase Security Rules.
We do not have user data.
Note: The server client libraries bypass all Cloud Firestore Security Rules and instead authenticate through Google Application Default Credentials.
If we change our write rule to write: if request.auth() != null our application fails to save.
However, we can call getAuth() and then signInAnonymously(). But how does that make it more secure? And how long will the function remain authenticated?
We have read the documentation at https://firebase.google.com/docs/rules/rules-and-auth and https://firebase.google.com/docs/firestore/security/get-started. But as we don't have users in our application, it seems unclear to us how to secure Firestore using firestore.rules.
Concrete: How do we secure a Firebase Firestore without using Firestore Authentication? Or is it a must?
When not using Firebase Authentication, you cannot get details of user who is making the request. request.auth will be null in this case and hence request.auth() != null fails.
When you use signInAnonymously() the user is signed in with Firebase Auth and request.auth contains details of that user. However, once the user logs out of an anonymous account by any mean, there is no way to log back in with that account and user won't be able to access their data again.
If you use your own authentication method, using Cloud functions to retrieve data would be best so you can authenticate user using your auth system and then serve data if authorized.

Firebase Firestore Security Rules for Backend Service

I currently have a GCP/Firestore Cloud Function writing to Firestore. And a NuxtJS client reading from said Firestore DB.
My NuxtJS client does not use user-based authentication. It is a news site that shows publicly available information.
I'm trying to configure the Firestore security rules to only allow reading/writing/updating from applications with an active service account for this Firebase project.
Currently, I'm getting an error on my client that says FirebaseError: Missing or insufficient permissions.
I have verified that the service accounts in question are still active and have the appropriate permissions.
I'm guessing that I'm missing something in my security rules.
My current security rules are as follows:
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.auth != null; }
}
}
Any direction is greatly appreciated.
I'm trying to configure the Firestore security rules to only allow reading/writing/updating from applications with an active service account for this Firebase project.
The security rules are effective on requests made using the Firebase Client SDKs only. The Admin SDK which uses a service account bypasses all security rules and has complete access to your Firebase project. Since the users don't have to login in your application, you can set all the permissions to false:
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
}
}
With these rules, only the Admin SDK can make requests to Firestore. If you are using runtime config to store your credentials, make sure the service account is in private so it can be access on server side only.

Is this Firebase/Firestore security rule for anonymously authenticated users safe?

I have a Flutter app that uses an API to pull data. My API key is the only thing stored in my entire Firestore database. My Flutter app retrieves the API key from Firestore and then uses it to fetch data.
My app also has anonymous authentication enabled. My app creates an anonymous user when the app is launched. My app does not allow users to create an account or sign up.
Below are the Firestore security rules that I currently have and I'm unsure if they can be improved to make them more secure from malicious attacks. My rules point to a very specific document myAPIKeyDocument, allows get only for authorized users, and does not allow write.
Are these rules safe as is or can they be improved if the only permission I want my app to grant is read access of my API key for anonymously authenticated users? And also, does if request.auth.uid != null; really make a difference at all since all users of my app will be automatically anonymously authenticated?
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /myDataCollection/myAPIKeyDocument {
allow get: if request.auth.uid != null;
allow write: if false;
}
}
}
If any user in your app having access to your API key is secure enough, then yes you are fine. Personally I would migrate any logic that requires an API key out of the client app and into Firebase Functions. That way you can more tightly control security to allow only requests from your app.
With anonymous authentication your current rules are about as good as it gets with the current structure of your project.

Your Cloud Firestore database has insecure rules. What rules would be best for a simple app?

I have received an email from Firebase stating the title of this post with these details:
We've detected the following issue(s) with your security rules:
any user can read your entire database
any user can write to your entire database
My Firebase database rules are as follows:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if true;
}
}
}
I am not sure what to do. For my app users need to be able to read mostly and write (sometimes to submit stuff). Does anyone have tips to secure this better, or even if I can do anything?
Do you use Firebase Authentication in your app? If yes, then change the security rules to this :
allow read, write: if request.auth != null;
This rule will allow only logged-in user to get and write data to database. This should be a good starting point for a simple app. However, if you are not using Firebase Authentication, then you must implement your own authenticate scheme, but this is just not recommended for security

How to get Firestore rules working with service accounts

As written in Firestore documentation here I have a security rule like this:
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userId} {
allow read, update, delete: if request.auth.uid == userId;
allow create: if request.auth.uid != null;
}
}
}
this rule works when I get authenticated with client library but not when I use server library as written in firebase documentation
Note: The server client libraries bypass all Cloud Firestore Security Rules and instead authenticate through Google Application Default Credentials. If you are using the server client libraries or the REST or RPC APIs, make sure to set up Cloud Identity and Access Management for Cloud Firestore.
How to replicate this security rule to service accounts roles?
Code that uses the Firebase Admin SDK with a service account to access Firestore currently can not be scoped to a particular user ID for the purpose of enforcing security rules. All access with the Admin SDK will bypass security rules and have full control of the database.
Note that this is different than Realtime Database, which does have such a feature.

Resources