I am curious if an user is able to write any data to the key they have writing permissions to. Ofcourse, normally this is done by authentication by the app they are using. But how well is it protected? If I am connected to my wifi I could use tamper data to change the network activities being send.
As stated here: Does firebase encrypt data with a unique key per account? It says that the data is encrypted before writing to the database. This however does not include changing the value's of the keys when the keys are not "arrived" at Firebase.
Is it possible to change the value's from monitoring the network activities, like tamper data?
Also, let's say these are some rules:
{
"rules": {
"users": {
"$uid": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
}
}
}
}
Is there any way a user could authenticate himself in any other way than using my app? How easy can a authenticated user change value's directly in the database, if he got write rules?
Thank you
In your provided rules, a user would be able to write arbitrary data to the node corresponding to their own uid, which can only be obtained via signing in with a form of Firebase Authentication (including minting a custom token server-side using the Firebase Admin SDKs).
100% of Firebase Realtime Database traffic is sent over TLS-encrypted connections. There is no way to man-in-the-middle this traffic and change it in flight.
You can trust Firebase Database Security Rules to do their job, but it is up to you to write robust rules that adequately protect data for your given application use cases. I'd recommend making use of .validate rules for structure and fine-grained .write rules everywhere. Another important tip to remember is that authorization is hierarchical. Once a .write rule is matched by a client all children of that node can be written by that client.
Related
I am writing an app using Firebase Realtime Database.
With the app, you can create votings, which can then be shared with anybody.
I use Firebase anonymous authentication.
I do not want users to need to register or login. So the votings are completely anonymous.
The Realtime Database has the following rules:
"rules": {
".read": "auth.uid != null",
".write": "auth.uid != null",
}
}
As far a I understand this means, only people using my app, which created the anonymous ID for them, are able to read and write the database, right?
Or would there be any other way somebody can access the database without using the app?
The auth.uid != null rule requires that the user is signed in to your project. It has nothing to do with whether they are using your app to do so.
Anyone can find the configuration data in your app, use that to call the same API that your app calls, create a user in your project that way, and then run whatever code they want (including deleting the root of your database).
To properly secure your database, you'll have to ensure the rules allow exactly what your code does and nothing more. This is typically easiest if you developer the rules hand-in-hand with the code of your app, instead of trying to add security after all the code works.
My recipe is usually:
Close off the database entirely.
Write code for one use-case.
See it fail, as the user doesn't have permission.
Change the rules to allow only that use-case, but nothing else.
Go back to step 2 for the next use-case.
A new option is to use Firebase App Check, which does reduce the chances of abuse by only allowing access from your app(s). You'll typically want to use App Check for broad protection, and then use security rules for fine grained control over who can access what data.
i have a serious Question. I am developing the Security Rules for my Firestore Database. So what if someone decompiled my App, stole the GoogleInfo.plist, added this file to his Project, and creates multiple Accounts with it? I mean in the security rules you have to:
allow create: if request.auth != null;
So he could add a new Document every time he adds an FirebaseUser Account.
How to solve and secure this?
Are there other options like sign in with custom field at example:
I create a document ID.
and so we check in the Firestore rules:
match /document/{myDOC}
allow write: if request.auth.code == myDOC;
So what I mean here is, if I can set additional Information to the Request of my App, and check if the additional Information is Equal to the myDOC;
Thanks!!
This is all working by design. There is no "security" information in GoogleInfo.plist. It just contains data that instructs the Firebase SDK on how to find your project and its resources. Without that data, your app would know nothing about your project.
To secure your database, you will need to design your database to allow for per-user security, then write rules that determine which authenticated users can read and write which documents, as suggested in the documentation.
It's not possible to send extra information along with a query for the purpose of security. You should depend on what Firebase auth provides in request.auth in the rules language.
See also: Is it safe to expose Firebase apiKey to the public?
https://firebase.google.com/docs/auth/admin/custom-claims
Firebase Admin SDK allows you to define custom attributes on user accounts.
admin.auth().setCustomUserClaims(uid, {admin: true}).then(() => {
// The new custom claims will propagate to the user's ID token the
// next time a new one is issued.
});
When you are writing your rules, it is possible to check these custom attributes.
{
"rules": {
"adminContent": {
".read": "auth.token.admin === true",
".write": "auth.token.admin === true",
}
}
}
But as it is stated in the docs, you should consider these points:
Use custom claims to store data for controlling user access only. All other data should be stored separately via the real-time database or other server side storage.
Custom claims are limited in size. Passing a custom claims payload greater than 1000 bytes will throw an error.
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.
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.
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.