I am working on a chrome extension, and using Cloud Firestore. As mentioned in Google's documentation, I have to put the code in the JavaScript file itself, which is easily visible to anyone who can extract the source code. For security purposes, we can allow access to database only through certain domain names or certain apps. But in the case of Google Chrome extension, it is neither being hosted with a domain name nor it can be registered as an app. So, how do I not let anyone mess around with it ?
And my second question is that I have some if statements inside the chrome extension code which relates credentials from Cloud Firestore and shows result according to it. Like this -
if(userrefdoc.getCoins < 1){
console.log("Not enough coins. Buy some more");
}
So, if someone can extract and modify my code, he can easily change the if statements according to his need and gets access to the features, which he is not allowed to use. So, how do I deal with this scenario too ?
It's impossible to hide secrets in code JavaScript code that you ship to customers to run in their browser or device (same for Android, iOS apps). You should assume that a determined hacker will be able to reverse engineer all the shipped code.
The Firebase init parameters are not "credentials". They are just settings that identify your project. There are no secrets in them.
The way to secure your data in Firebase is to use Firebase Authentication along with Firestore security rules. If you can't use Firebase Auth or security rules to to control access to your database to individual users authorized to do so, but you need public client code to read and write it, you should assume that anyone with the name of your project will be able to read and write it.
The only workaround for this involve you setting up your own backend, routing all access through it, and performing your own checks to see if the client should be able to do.
Related
Offline persistence in Firestore enables the browser to store records that were not uploaded to the server (offline) even after the session was closed (Browser exit)
Please see: https://firebase.google.com/docs/firestore/manage-data/enable-offline
However, firestore does not offer any officially supported way to clear the Chace when a user logs out from his session. Please refer to: https://youtu.be/qGAIimfrBB4?t=257
Recently they released the function clearPersistence, but they clearly state that is not meant for security reasons and recommend to disable Persistence if security is an important factor for you. Please see: https://firebase.google.com/docs/reference/android/com/google/firebase/firestore/FirebaseFirestore#clearPersistence()
Note: clearPersistence() is primarily intended to help write reliable
tests that use Cloud Firestore. It uses an efficient mechanism for
dropping existing data but does not attempt to securely overwrite or
otherwise make cached data unrecoverable. For applications that are
sensitive to the disclosure of cached data in between user sessions,
we strongly recommend not enabling persistence at all.
I want to understand better what's the security hole with using "ClearPersistence" on logout of the user.
Anyone experienced with that? Any other working solution that enables you to remove all the Firestore cache after a logout?
There is no guarantee that your code will run in the browser (or any other client). For example: a malicious user can take the configuration data from your application, and call the API to get access to the same data in your project, but then store it wherever they want.
Another malicious user might prevent the app from clearing the local cache, or quickly copy the local cache file to another location to have a copy before it is cleared.
And these are just two if the simplest examples. The simple fact is that you should assume that any data that exists/persists on the client can be seen by any user who has access to that client.
My Firebase database is fully readable for anyone, because the content is of course going to be used for a websit. As you know, Firebase has a download limit (10GB/month), and if someone wanted to they could write some code to download the whole thing over and over 'til the limit was reached. Now, can i prevent a full download but still have everything accessible in parts, as intended?
There is no way in Firebase's server-side security rules to limit based on the size of the data users can read at once.
You'll typically control access by making the data not globally readable. Instead you'll want to make it readable by following a certain structure, which matches with how you access the data in your web site.
If you suspect your web site is seeing abuse, reach out to Firebase support for personalized help in troubleshooting
I want to display the number of times a video has been viewed using the core reporting API via Javascript. However, the API is designed with OAuth, for building applications and not just logging into my account to get the event count.
Is there a way to login for just my account via Javascript?
Thanks,
Matthew.
I think what you are looking for is a Service account. To my knowledge you cant use a Service account with JavaScript due to security issues with the key file.
What you could try and do is to authenticate the script once using normal Oauth2 then save the refresh token to the file and hard code that into your script and send that. But I wouldn't recommend it as then anyone that checks your script will also be able to access it. So basically you have the same security issues you had with using a Service account.
As you can see doing what you are trying to do with JavaScript isn't really going to work. As you can see this is something I have also tried unsuccessfully in the past to do. I recommend you try and do this with some kind of server sided scripting language, like PHP.
Google analytics tracks pageviews.
I would like to use JavaScript to fetch the number of views that a specific page URL has.
How can I do this?
P.S. Google documentation is a mess, all I can find out from it is how to setup tracking.
Doing this purly in javascript is going to be tricky. Due to the fact that you will need authorization to access your data.
Now normaly for a case like this I would say use a service account but in order to use a service account to connect to google analytics, you will need to download a key file. This file must be kept save and secure.
Javascript is client side scripting how can you send a file that no one else should be allowed to access? As far as I know there are no javascript examples for using a service account to access google analtyics i have also been unable to come up with a safe and secure way of doing this myself. If any one has any ideas please comment i would love to hear how you got this working.
The only other option is to go with normal autentication the problem with this is that you will need to autenticate the script. Thats not hard you could then save the RefreshToken some place and pass it to the page. Again this is a problem anyone that then looks at your source code will have the RefreshToken and the ability to access your data.
My recomendation: Use some server sided scripting language like php for example.
If you want to look at the code for doing this in javascript Hello-analytics-api
I've read about Firebase and it looks awesome for what I want to do.
I've read about authentication and how based on rules certain logged-in users are authorized to do different stuff. Al good.
However, I'm unsure about another type of security: how do I make sure that only my own site (using client-side javascript) can talk to my firebase-backend? I'm asking because afaik there's no way to prevent anyone from looking up my firebase endpoint from the client-side code (url pointing to my specific firebase backend) and start using that for god knows what.
This is especially worrisome in situations in which I want to open up writes to the anonymous user role. (e.g: some analytics perhaps)
Any help in clearing my mind on this much appreciated.
Update (May 2021): Thanks to the new feature called Firebase App Check, it is now actually possible to limit calls to your backend service to only those requests coming from iOS, Android and Web apps that are registered in your Firebase project.
You'll typically want to combine this with the user authentication based security that Kato describes below, so that you have another shield against abusive users that do use your app.
In my opinion, this isn't so much a question about Firebase's security as a general discussion of the internet architecture as it stands today. Since the web is an open platform, you can't prevent anyone from visiting a URL (including to your Firebase) any more than you can prevent someone from driving past your house in the real world. If you could, a visitor could still lie about the site of origin and there is no way to stop this either.
Secure your data with authentication. Use the Authorized Domains in Forge to prevent CSRF. Put security rules in place to prevent users from doing things they should not. Most data writes you would use a server to prevent can be accomplished with security rules alone.
This is actually one of the finer qualities of Firebase and API services in general. The client is completely isolated and thus easily replaced or extended. As long as you can prove you're allowed in, and follow the rules, where you call in from is unimportant.
Regarding anonymous access, if you could make them visit only from your site, that still won't stop malicious writes (I can open my JavaScript debugger and write as many times as I want while sitting on your site). Instead, place tight security rules on the format, content, and length of data writable by anonymous users, or save yourself some time and find an existing service to handle your analytics for you, like the ubiquitous Google Analytics.
You can, of course, use a server as an intermediary as you would with any data store. This is useful for some advanced kinds of logic that can't be enforced by security rules or trusted to an authenticated user (like advanced game mechanics). But even if you hide Firebase (or any database or service) behind a server to prevent access, the server will still have an API and still face all the same challenges of identifying clients' origins, as long as it's on the web.
Another alternative to anonymous access is to use custom login, which would allow a server to create its own Firebase access tokens (a user wouldn't necessarily have to authenticate for this; the signing of the tokens is completely up to you). This is advantageous because, if the anonymous user misbehaves, the access token can then be revoked (by storing a value in Firebase which is used by the security rules to enforce access).
UPDATE
Firebase now has anonymous authentication built into simple login, no need to use custom login for common use cases here.