Firestore security rules in auth less apps - firebase

I've developed an app which relies on Firestore for storing some user's data. This app doesn't have any login mechanism, as it uses the device UUID as identifier; we're not managing any sensitive data, btw.
I'm getting daily warnings from Firestore regarding the absence of security rules in my database, but as long as I don't have any login mechanism and my users need to both read and write from it, I can't see any way for implementing a useful security rule.
Is there any pattern I could follow in this situation? Is there any way to create a security rule for allowing to only read and write data created by the same user without any user authentication?
Thanks in advance

It sounds like you want to identify the user, but then without authentication. My guess is that you want to identify them, without requiring them to provide credentials.
If that is the case, you're looking for Firebase's anonymous authentication provider, which assigns a unique, unspoofable ID to each app instance. Signing in anonymously takes very little code, for example for Android it's:
FirebaseAuth.getInstance().signInAnonymously();
After this call completes, the user has an ID that you can then use in your security rules to identify the data from this user.

Related

How to save user data in db, without logging in?

I am working on a simple app that allows users to search for something using an API and save it to view later.
However, I don't want to integrate authentication in the app. I can, but would rather not as a UX decision. Do you know of a way to generate a device token, that is unique to every device and can be used to store which assets a device has saved in the db?
I am thinking of expo push tokens as a possible solution, but that would require users to accept push notifications - so what happens if a user says no?
Sounds like you could just use react-native-uid to generate a unique id for your device and then store it in AsyncStorage and fetch it from there going forward.
For more inspiration, or perhaps just a more canonical way to do this... read up on suggestions surroundings the recently deprecated constant for installationId here:
https://docs.expo.dev/versions/latest/sdk/constants
I haven't used this before but if you're looking for something bullet proof then this is probably your goal of getting the same concept.
Firebase Anonymous Authentication might be ideal to use in this case. This can be used to create a user in Firebase auth without any credentials and can be useful especially when you are using either of Firebase's databases since you can use security rules with user's UIDs.
However, once the user logs out of the account by any means including but not limited to using sign out option in your app, clearing app data or uninstalling the app, the same account with that UID cannot be recovered. I looked up for AsyncStorage and apparently that gets cleared to if the app is deleted.

How can any user write to my database securely in Firebase without Auth?

So if I have an E-commerce App that doesn't require Login/Auth, and my users buy in the store, then after verifying the transaction the backend writes the order in the database.
The thing is that my Realtime Database just relies on Stripe transaction key (i.e, someone has paid for an item) to be able to write on the DB, because my rules are set so anyone can write, otherwise I would need every user to log in, but that's not what I want.
Firebase recently notified me that my rules are weak.
How can a make sure my users are able to write to my database in a secure way for my app, without log in/Auth?
There are many different security models you can use with Firebase, and it's important to understand the level of security each provides.
One thing to look into is anonymous auth which lets you "authenticate" a user without actually requiring them to provide any credentials. This provides a way to guarantee that the same device is being used between multiple reads/writes.
In your specific case, it sounds like you might be looking to rely on unguessable tokens. This can be a valid security model for some use cases so long as the key is sufficiently complex as to be unguessable.
At its most basic, the way you'd structure security rules for unguessable URLs is something like:
{
"rules": {
"transactions": {
"$key": {
".read": true,
".write": true
}
}
}
}
This allows users to read/write specific nodes at e.g. transactions/abc123xyzunguessable but importantly does not allow reading/writing to the parent transactions node. Security comes from the fact that only the person who originally got the unguessable token will be able to provide it again in the future.
A better implementation would gate writing on the $key matching the expected unguessable format, adding validation and other read/write rules to ensure that the data is formatted appropriately, and probably also prevent modification of key fields.
These are just some pointers but should help you on your way. The important thing is to make sure that you never leave important information in a place where it can be read through easily guessable URLs.
There is no "secure" way to allow writes to Realtime Database without Firebase Authentication. Without Firebase Auth, either there is full public access, or there is no public access at all.
If you can't use Firebase Auth, what you will need to do instead is make your security rules disallow all direct access to the database from client applications, then create backend APIs to manage access to the database. Your backend APIs will need to somehow validate that the person making the request should have the ability to make the required changes. Then, it will have to use the Firebase Admin SDK to commit those changes to the database.

Extending Firebase Users

I am currently building a multi-platform web application and I'm currently busy with the authentication of users. I'm using vue on the client-side and django and the backend with postgres as the db.
I thought I would try out using firebase's authentication as it would speed up the process as well as take care of various issues like security etc. I have now come across a bit of a problem:
I need to add extra fields the user (gender, address etc.)
I need to set user roles (admin, manager etc.)
I am aware about some kind of way to set user roles but not really sure. In terms of extending the user in my mind I have two ideas:
Either I use the UID from firebase as a identifier to an extended user class
in my backend db. But that kinda defeats the purpose of speed.
Use Firestore - not sure how I would go about doing this though.
plz help
I have written a blog and made a video on how you can use custom claims to assign roles to your users. Essentially, you apply custom claims on a secure backend like inside of Cloud Functions, and these can be used to control access to Firebase backend features like Cloud Firestore and the Realtime Database. You can also check out the Firebase guide for more information.
As for additional data about a user like gender and addresses, that should be stored in Cloud Firestore, the Realtime Database, or whatever database you choose to use. It is not information that you constantly need when accessing a User object.

Do I need security rules on my Firebase Database?

It is unclear whether or not to set security rules for database.
Is it enough to just let in just authenticated users? Do I need more complicated things? I have android app, and do all validations and updates inside app.
The video from IO says that there is possibility that someone can get all your data if he knew your app ID. So if user is authenticated and have app ID and somehow build web app he can get data too? I mean if using simple rules.
I`m asking for risks when building just android app and using simple rules (auth is on).
Is it ok for you if any user could edit/create/delete any data in your Firebase database? If this is not ok, you need security rules (you probably need them)
Firebase's security rules are really powerful and easy to use, I suggest you take a look at the documentation.
You need user id or role specific rules, otherwise somebody for example can easily wipe out your all data, or easily manipulate anything.

Setting permissions on Apigee BAAS

What's the best way to set permissions on objects in Apigee BAAS entities, collections in such a way that Users can edit what they create, and others can read them? There might be a case for Admins to be able to edit everything as well.
I asked a similar question here Securing apigee baas that was more around securing the app id/secret which would be needed to make the call to update permissions, but I was wondering if there is any best practice around doing this sort of thing from a mobile application.
My initial thought would still be the service callout (not sure how Apigee-127 which was mentioned in the previous question would be any different to a service callout directly to the BAAS as to me 127 looks like I'm just writing my apis in Node.js rather than using the edge console), but I don't know if there is an easier way in terms of securing all entities, in specific collections ,created by specific users? I guess I could add a created by column which I could check from an app perspective, but this wouldn't stop someone from potentially hitting the BAAS directly and retrieving this info unless permissions are also set at an entity level requiring a user access token.
Is it possible to secure the BAAS in such a way that only calls from Edge can hit the BAAS url?
(Disclaimer: I have not tried this myself but here is a suggestion.)
API BaaS Automatically sets the path segment to the UUID of the currently authenticated user when $user is used. For example, if you sent a request with a valid access token for a user with UUID bd397ea1-a71c-3249-8a4c-62fd53c78ce7, the path /users/${user} would be interpreted as /users/bd397ea1-a71c-3249-8a4c-62fd53c78ce7, assigning the permission only to that user entity.
In this way, through your application, you can set permission for each user, and each object as soon as the objects are created from your application. Assuming you have the user authenticated, of course.
Ref: http://apigee.com/docs/api-baas/content/using-permissions

Resources