Firebase's version of SQL Injection - firebase

Using firebase for the first time after a strong background of SQL. I'm used to using functions like addslashes() to sanitize user input into queries.
Is there any standard way of doing the similar thing with Firebase lookups?
For example:
// expected a key, not a path
var userProvidedKey = "3/malicious"
// will not be a ref to what I expect
var ref = firebase.database().ref(`something/${userProvidedKey}`)
I don't know how malicious it can be for a user to be able to search further down in a ref, but maybe this problem is solved? Or do I need to .split('/').shift() any inputs that I receive?
Note: Using the JS SDK for my examples.

Input/output should always be sanitized and validated before entering the database.
Firebase provides security and data validation checks to be used in your application. Firebase also provides rules in its database to determine which users have write/read access to which data in the database.
For more information read the documentation about the Firebase realtime database.
Found this thread Adding Firebase data, dots and forward slashes that may answer some practical questions on Firebase specific sanitation.

Related

how do I wait for a response from FireBase Kotlin Android Studio

Screenshot-1
Screenshot-2
I am trying to check in the database whether there is a user with such a login or not. If it exists, then display an error.How can I get a response from the database before I create a user
That's not an efficient way of handling authentication. The best option that you have in my opinion, would be to implement Firebase Authentication. Once you do that, you can simply check if the user is authenticated or not. How? By simply checking if the FirebaseUser object is null or not. Please also note that this operation is not asynchronous.
If you however need to get something from the Realtime Database, then please note that that is indeed an asynchronous operation. Since you're using Kotlin, the following article will help for sure:
How to read data from Firebase Realtime Database using get()?
Edit:
If you want to check if a user already exists, then please check my answer from the following post:
Checking if a particular value exists in the Firebase database
Besides that, never store credentials in plain text. I highly recommend you implement Firebase Authentication so you can secure your database using Firebase Security Rules. If you want to keep your own authentication mechanism, please see the official document regarding that:
https://firebase.google.com/docs/auth/android/custom-auth

Why does Google Firebase Cloud Firestore has "write", "update" security rules, while we should not allow users to write directly on database?

I'm implementing an application that using Google Firebase Cloud Firestore. Because my application has a lot of small write requests, it will be very costly if I use Firebase Cloud Functions in the middle. Therefore, I asked a question on Should we allow users to write to database directly. All responses said that I should not do so. Then, why does Google Firebase Cloud Firestore has "write", "update" security rules? Users should not write to the database anyhow.
EDIT (responding to DIGI's comment & answer):
From the answer, it seems like we can use the firebase rule instead. Then, how should we correctly use them?
For example, my app is recording user's location when they turn on the map & update it to the database so that user's friends can see it in real-time. How should I ensure that the data is in the form {longtitude: double, latitude: double, timeStamp: TimeStamp}, and the user doesn't change any other few in the document?
This is a common misconception from standard MySQL databases and similar where a server acts as a layer of logic and sits between the client and database.
Firebase still has this layer of logic in a simplified version known as security rules which allow basic read and write operations from the client. The design is by shifting computing power from the server backend onto the client instead, saving in server computing costs on their backend by distributing that requirement to users' devices.
The concerns listed in SE are from people who are unaware of the limitations and restrictions you can place inside rules and your project to control what can be requested with firebase and your app.
To clarify, Firebase does not hide your database keys, they are easily accessible and yes, a user can theoretically make a client using your database backend. but so long as rules are in place, conditions defined, Cors configuration, and app origin settings are enforced, you can prevent all of this.
For multiple writes, Realtime is ideal since it can handle data faster and more cost-effective than Firestore writes.
So my example will respond with the intent of realtime database per your edit.
{
“rules”: {
“location”: {
“$uid”: {
“.validate”: “newData.hasChildren(['longtitude', 'latitude', 'timestamp']) &&
newData.child('longtitude').isNumber() &&
newData.child('latitude').isNumber() &&
newData.child('timestamp').val() <= now”,
}
}
}
}
I highly suggest getting familiar with some core concepts
https://medium.com/#juliomacr/10-firebase-realtime-database-rule-templates-d4894a118a98
Full documentation here: https://firebase.google.com/docs/reference/security/database

safe security rules for cloud firestore (firebase) without user authentication

I need to write safe security rules for a flutter project that doesn't require user authentication (for a reason) for creating new documents.
For all other actions you need to be authenticated.
People are only allowed to create a document if they use the app too.
Is it sufficient if I just limit the amount of created documents in a specific time (with timestamps) and also limit the size, or do I still need to consider something else?
I'm new to firebase but I kind of know that there are ways to do firebase-actions without the app (that will be creatable from the project) via commands if you just get the project-id.
For example that would be a case which I haven't considered yet.
Regarding the last point:
There are three Api keys in the google cloud platform firebase project:
An Android key, an IOS key and a browser key. (auto created by Firebase)
I thought, maybe if I'd apply a restriction to the Android key, so that only Android apps can use it and likewise for the IOS key, the problem could be solved, but I'm not sure.
(I then would restrict the keys via the Google Cloud Platform Project of the Firebase Project.)
People are only allowed to create a document if they use the app too.
This requirement is not enforceable on Firebase. Anyone can take the configuration data from your app, and use that to call the same APIs in the same way. As long as the calls meet your security rules, they will be allowed. And since there's no security rule clause that says "only from my app", you can't limit access to only people using your app.
Is it sufficient if I just limit the amount of created documents in a specific time (with timestamps) and also limit the size, or do I still need to consider something else?
How do you want to limit the document creation in time? If you want to do this per user, you'll need to know the user.
I recommend looking into Firebase's anonymous authentication, which gives user's of your app an ID without requiring them to enter credentials.

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.

Hashing algorithm support in firebase real-time database security rules

I would like to compute hash functions inside security rules.
md5hash(auth.token.email) === $hashedvalue
Is there a way for me to do that in bolt? or natively in firebase real-time database?
Use Case:
Basically I would like to store the email as the key in the firebase real-time database and use it in the firebase security rules for authentication and authorization. Since few special characters like dots (.) are not supported in keys I was thinking of using some hashing algorithm which is available in firebase real-time database.
auth.id doesn't work in my case as I'm not giving any sign up option as I have a pre defined set of users with pre-defined profile details accessing my application through their Google login (which I know the email ID of) to start with and since they haven't yet logged into my application I don't have a corresponding ID to authenticate or authorize them on their first attempt.
This page of documentation shows all the functions available in Realtime Database security rules. There are no hashing functions there. You could file a feature request to explain you use case.
For the sake of posterity, I got this working with a small workaround (Yay!).
From the fire firebase real-time database documentation I found out that firebase security rules supports an amazing string function called "replace" xD.
So now I pre process the email Ids by replacing all the characters not supported as database key with their url encoding equivalent before creating the key and use the same set of replacements in my firebase security rules.

Resources