The situation is that I have a website, where at the end the user can order with filling a form, but no registration or log in is required, to be more specific, there's no possibility to register or log in. When the form is filled, with the submit button I want to validate the input with a function, and if they are valid, send it to Firebase. There are a few problems:
there's no possibility to authenticate the user, I need to set the Firebase security rules as "open", so everybody can write and read data to the database (but it may be a good solution to set as everybody can write, but just I can read data.
I read a bit about the config variable, and there's no good possibiity to hide that, so if somebody write a simple js program, and set the config as it's in my file, it can do whatever it want with the database
I was thought about that is it really the best solution to read the users input as order, I was thought about that maybe js can somehow send me the data to my e-mail address, but after careful research, I can't found a possibility to that. Anyways, it's sure that there's a solution to the Firebase problem. What I want is to set the only possibility to write to the database through the website, and read the data just through the Firebase Console.
There's not much you can do if you aren't authenticating your users, I guess the best option would be to set up write rules to protect the integrity of the data being saved (so even if someone with access wrote to it they'd have to follow a structure): https://firebase.google.com/docs/database/security/securing-data and set read rules to nobody.
Another method may be to have an API on a backend server which makes sure all requests are coming from your website only before saving it to firebase. This way you won't have to expose your firebase config.
In addition to #AlchemistShahed's answer, I'd recommend checking out Firebase's anonymous authentication. This gives each user an ID, without requiring them to specify any information. It's pretty much a persistent session ID, with as little code as:
firebase.auth().signInAnonymously()
By embedding this (anonymous) user's UID into the data they write to the database, you can easily detect when a single user is flooding your queue with data.
You could write a cloud function that would be called on form post, that function would check and sanitize data before inserting data into Firebase. Since data insertion would be done from the server side, no config would be present client side. Then set security on Firebase so only you can read.
You can also check those links, you might find something else in there.
Here's a link to some common use case for Firebase rules:
https://gist.github.com/codediodeio/6dbce1305b9556c2136492522e2100f6
Here's a link to Firebase security doc: https://firebase.google.com/docs/database/security/
Related
A hacker was able to create users in my client side based firebase site, I was restricting account creating by some sign up conditions on user's signup form data, I think he just injected signup code,
I immediately disabled authentication and removed the malicious accounts
If I used firebase cloud functions, will this hack still be able to create accounts, since firebase configuration was available to any client
are there any other actions ?
Update 4-9-2022
as temporary solution until using cloud functions, I made use of
making conditions using
https://firebase.google.com/docs/database/security/rules-conditions
if a user was created bypassing my logic I will make rules to disallow him from accessing certain paths
If you didn't do this already. You could fix this by adding some email verifier functionality. Or maybe try adding a captcha
Also check out: https://firebase.google.com/docs/auth/web/email-link-auth
Blocking the user by IP-address is pretty useless, so I can't really come up with another solution.
One question that you could ask yourself is, What is the reason they are doing this? If it is nothing too serious you could just accept and delete all those accounts after the "hacker" stopped making accounts.
I am doing a Website 100% in ReactJS, It's a simple/medium complex, this has a Login, Profile and other sections more. After Users Log into the site the login callback returns some important values like: "Token, UserRole". Currently I'm storing these values in Web client using localStorage .
My doubt is the next: There is a better way to store this values? Because if any person changes the value from the Browser Console this could be a BIG ISSUE because they could change the role and then execute things that they never should do.
I thought to do it with Redux, but if the users Refresh the website then they lost the values, so I am not pretty sure to choose this.
What do you think guys?
TIA!
The general rule is to never trust any data stored client-side, except for an authentication token or the equivalent. All changes that the user makes that involves the server should be verified on the server. So, rather than:
if any person changes the value from the Browser Console this could be a BIG ISSUE because they could change the role and then execute things that they never should do
Instead, the right thing to do would be, when the client wants to do something (such as edit their profile), have the client send their authentication token (or session ID) with the rest of the payload to your server. Have your server examine the token, check that the user associated with the token actually does have the required permissions for what they want to do, and only then continue to process the request.
Whether you also happen to store some information in Redux or elsewhere has no impact.
Storing login-related information client-side is relatively common and isn't inherently bad - just make sure to always verify it on the server when something that requires permissions is requested.
One approach some use is for the server to create an encrypted JWT that only the server can decode, which gets sent with requests.
I have already found many answers about this like link
But I don't think it really solves my problem,
I still can easily get my database instance in client side:
firebase.initilizeApp(config);
db = firebase.firestore();//db can be considered as an instance
Then simply type code in Chrome console:
db.collection("abc").where("id","===","1").get().then(function(){//do something})
to get my data.
However I still want the client side is able to do CRUD but only through the page events like click or drag or something else.
So in such situation, is it possible to achieve it?
When you add a website to your firebase project where you would like to access the database, you're defining which URL cann access the database...
Checking authentication and integrity needs to be managed by the database rules though.
Therefore, once you've connected to the app and can fetch data, you can of course also do CRUD operations and create/read/update/delete data in there...
If you want to, you can of course also utilize Firebase functions as a bridge between website and database... there you could define REST-Calls that write or read from the database. However, you need to make sure to add authentication stuff there as well to prevent unallowed access.
I am trying to understand/anticipate the security considerations associated with using firebase as a backend.
The documents cover authenticating users and validating input, but I can not find any discussion of risk associated with malicious users trying to inject javascript into the database.
Is it possible that javascript could be included in an input field that is saved to the database that then could be executed later when that code is retrieved and displayed elsewhere?
Or is firebase escaping or sanitizing data somehow?
Any database (or other storage system) can be used to store malicious code as it is inherent to their function: they just store data.
The Firebase SDKs and supported libraries (such as AngularFire, EmberFire and ReactFire) ensure that they never embed the information from the database into HTML pages unescaped. While it is always possible that we (I work for Firebase) missed something there, I don't recall that ever being reported.
You have to properly escape all user input when putting it in a webpage regardless of the backend.
Firebase offer validation of data, there you can check for injecting javascript snippets into your database.
https://firebase.google.com/docs/database/security/securing-data#validating_data
And you should always sanitize your output, this is not related to Firebase but a good rule of thumb.
I know that direct access to a database via Javasript is not recommended, since the user would get the database login and thus the ability to manipulate the database.
But in my case, the user cannot see the client-side code, since it's a phonegap app.
Is there a way to do it? And it not, what is a good way to do with a serverside part?
its really not recommened to access database from client-side its not only for security reasons, but what if you changed the database access or upgrade to different database, so you will have to change it in your app which you may not be able to access again after users installed if its mobile app and then you stuck to your database for ever,
so whatever you want to do you can add an action in server-side and depend on your params it will formulate your Query,
for example sending parameter for user=true this will search for users tables, sending parameter for account=true will search in users-accounts tables and so on.