i am building a chat android app that allows users to chat where users can create account and use all the features. It's about to be completed but there's a problem, actually a question.
Is firebase on android safe ?
In my firebase database, i have created a rule as follow:
{
"rules": {
".read": "auth != null",
".write": "auth != null"
}
}
Now, this rule will reject any non authenticated users from accessing the data and pushing data or deleting any of it. But, when user creates an account on my chat app, he/she will be authenticated and my app will allow to make modifications. What if they reversed engineered the app and changed some of the codes and pushed invalid datas or removed some of the values from database coz they are already authenticated ?? How can i prevent that ?
When user creates account in my app i use:
auth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(RegisterActivity.this, new OnCompleteListener<AuthResult>() {
This will create a new chat user for the app. So, user is creating his/her own account and they know the credentials and everything. I am so confused, how can i prevent them from editing my codes ?
You can't prevent malicious clients from executing whatever code they want against your Firebase project. Someone will always find a way to compromise your app at runtime on a device that you can't fully control.
The way to protect your data is through sophisticated security rules that:
Requires users to be authenticated (as you already have)
Decide which users can read and write to which locations in your database
Reject invalid data from being written
This requires a fair amount of thought and effort. You can start with the documentation to learn more.
Please also read this question on Quora for some more ideas.
Related
I am working on one the Android APP & want to integrate it with the Firebase & it's Realtime Database. I have a list of 1000 users(Excel) with details like EmpId, EmpName, Team, Mobile Number, etc.
I want to restrict my APP only to the users from this list & also want to authenticate them using the mobile number present in the list against there name.
Can I use Firebase Auth for the above requirement & if yes, how to do that?
If with FireBase Auth, this is not possible what is the alternative solution?
Please help.
Firebase Authentication only allows the users to identify themselves. What you're describing is limiting what users are allowed to use your app, which is known as authorization, and Firebase Authentication doesn't handle that.
Luckily you tagged with firebase-realtime-database too, and authorization is definitely built into that. What I'd usually do is create a top-level node in the database that contains the UID of users that are allowed to use the app:
"allowedUsers": {
"uidOfUser1": true,
"uidOfUser2": true
...
}
Then in other security rules you'll check if the user's UID is in this list before allowing them access to data, with something like:
{
"rules": {
"employees": {
".read": "root.child('allowedUsers').child(auth.uid).exists()",
"$uid": {
".read": "auth.uid === $uid && root.child('allowedUsers').child(auth.uid).exists()"
}
}
}
}
With these rules:
Allowed users that are signed in can read all employee data.
But they can only modify their own employee data.
Of course you'll want to modify these rules to fit your own requirements, but hopefully this allows you to get started.
A few things to keep in mind:
The UID is only created once the users sign up in Firebase Authentication. This means you may have to map from the email addresses you have to the corresponding UIDs. You can either do this by precreating all users, do it in batches, or use a Cloud Function that triggers on user creation to add the known users to the allowedUsers list.
Alternative you can store the list of email addresses in the database. Just keep in mind that somebody could sign in with somebody else's email address, unless you require email address verification. Oh, and you can't store the email address as a key in the database as-is, since . characters are not allowed, so you'll have to do some form of encoding on that.
Also see:
How do I lock down Firebase Database to any user from a specific (email) domain? (also shows how to check for email verification)
Restrict Firebase users by email (shows using encoded email addresses)
firebase realtime db security rule to allow specific users
How to disable Signup in Firebase 3.x
Firebase - Prevent user authentication
I know it's late but for anyone who may be referencing this question, my recommendation is blocking functions. You essentially create a Firebase Cloud Function that can accept or deny requests to make an account. Here's what it could look like:
const functions = require('firebase-functions');
exports.beforeCreate = functions.auth.user().beforeCreate((user, context) => {
var allowedUsers = ['johndoe#stackoverflow.com'];
// if they are not in the list, they cannot make an account
// throwing this error will prevent account creation
if(allowUsers.indexOf(user.email) == -1) throw new functions.auth.HttpsError('permission-denied');
});
This way is better in my opinion because the security rules doesn't have to reference the database. Instead, the security rules can allow requests from any authenticated user, because the only authenticated users are ones allowed by this function.
I have made an android app and using Firebase realtime database as backend. In the app i have some In-App purchase products too. These products are abount buying points(such as 150 points, 1000 points etc.). The problem is right now i am seeing that some users increasing huge amount of points to their profile. For the sake of relatime view of firebase database i am seeing that their points increasing like 50k, 100k. But i don't have any In-App purchase product with this huge amount. I am tired of disabling their account & can't find a way to prevent it.
I know some app that are used to hack points/coins like Freedom APK and some other. But these apps require the device to be rooted. So on App launch i checked whether the device is rooted or not. Right now rooted device are not allowed to use my app. Still they are hacking points.
I am using following database rules
{
"rules": {
"Users": {
"$userID": {
".write": "auth != null",
".read": "auth != null"
}
}
}
}
And database structure is:
Users-
uId:
userEmail
userName
userPoints
The workflow of valid point increase is:
User buy a In-App product --> User points increase as per the product value
User watch a rewarded video ad --> User points increase by +8
I want to prevent these hackers to generating points.
I am no expert with android and realtime database but the problem is that the user have write access to the database.
I do not know how but they somehow can manipulate the data which is sent to your database.
You need to validate the data before it is written to your database.
You could do some validation with security rules but in my opinion the easiest way is to use callable cloud functions to validate your data and revoke the write access to your database.
If the user buys points they should call a cloud function which verifies if the data is valid. If the data is valid the cloud function updates the database. This way the user can not manipulate their points.
For my online shop i use cloud functions to verify the cart content on checkout and the users can not directly write to the database.
You should do something similar.
Edit:
Here you could find an introduction to cloud functions.
https://firebase.google.com/docs/functions
And here you could find some information about callable cloud function which i recommend. With a callable function you can invoke the backend function directly from your code without an API call.
https://firebase.google.com/docs/functions/callable
How do I prevent other users from accessing my Realtime Database via my Firebase URL? What must I do to secure it to only my domain?
First of all, understand that you cannot secure any URL on the internet according to the origin domain--malicious users can simply lie. Securing the origin domains is only useful in preventing cross-site spoofing attacks (where a malicious source pretends to be your site and dupes your users into logging in on their behalf).
The good news is that users are already prevented from authenticating from unauthorized domains from the start. You can set your authorized domains in Forge:
type your Firebase url into a browser (e.g. https://INSTANCE.firebaseio.com/)
log in
click on the Auth tab
add your domain to the list of Authorized Requests Origins
select a "provider" you want to use and configure accordingly
Now to secure your data, you will go to the security tab and add security rules. A good starting point is as follows:
{
"rules": {
// only authenticated users can read or write to my Firebase
".read": "auth !== null",
".write": "auth !== null"
}
}
Security rules are a big topic. You will want to get up to speed by reading the overview and watching this video
Setup security Rules,
source to learn : https://firebase.google.com/docs/rules
Use Emulators (It will make keys not easy to visible by beginner programmers)
, source : https://firebase.google.com/docs/rules/emulator-setup
Cloud Functions (It will hide the names of Collections and Docs)
, https://firebase.google.com/docs/functions
Limit the API keys to specific website/s(It will make peoples unable to access your website/app from outside)
if someone knows more methods, please tell, no one can be perfect.
Sorry if this seems like a dumb question but the Firebase docs go round in circles.
I'm building an Android app and I'm authenticating users using mAuth.createUserWithEmailAndPassword documented here - https://firebase.google.com/docs/auth/android/start/
That's straightforward and I can set the username, email etc. and its all stored somewhere (I've no idea where as its not displayed in the Firebase console) BUT I'm confused about user based authentication - https://firebase.google.com/docs/database/security/user-security in the examples here (and elsewhere on the net) we see the rules starting with users
{
"rules": {
"users": {
"$user_id": {
// grants write access to the owner of this user account
// whose uid must exactly match the key ($user_id)
".write": "$user_id === auth.uid"
}
}
}
}
As far as I can see in the Firebase console there is no users child node in the database generated automatically from mAuth.createUserWithEmailAndPassword. So my question is should I create this or was a users child automatically created I just can't see it?
Its not a lot of work to implement an additional user child node and store user information there but it seems like a lot of duplication given that the authentication procedure has already stored the user information somewhere. The opposite way to ask this question is can I add the db write rules above and expect them to work if I have authenticated users but never added a users node in the db myself?
Why the docs don't spell this out is beyond me
How do I prevent other users from accessing my Realtime Database via my Firebase URL? What must I do to secure it to only my domain?
First of all, understand that you cannot secure any URL on the internet according to the origin domain--malicious users can simply lie. Securing the origin domains is only useful in preventing cross-site spoofing attacks (where a malicious source pretends to be your site and dupes your users into logging in on their behalf).
The good news is that users are already prevented from authenticating from unauthorized domains from the start. You can set your authorized domains in Forge:
type your Firebase url into a browser (e.g. https://INSTANCE.firebaseio.com/)
log in
click on the Auth tab
add your domain to the list of Authorized Requests Origins
select a "provider" you want to use and configure accordingly
Now to secure your data, you will go to the security tab and add security rules. A good starting point is as follows:
{
"rules": {
// only authenticated users can read or write to my Firebase
".read": "auth !== null",
".write": "auth !== null"
}
}
Security rules are a big topic. You will want to get up to speed by reading the overview and watching this video
Setup security Rules,
source to learn : https://firebase.google.com/docs/rules
Use Emulators (It will make keys not easy to visible by beginner programmers)
, source : https://firebase.google.com/docs/rules/emulator-setup
Cloud Functions (It will hide the names of Collections and Docs)
, https://firebase.google.com/docs/functions
Limit the API keys to specific website/s(It will make peoples unable to access your website/app from outside)
if someone knows more methods, please tell, no one can be perfect.