DEV Community

Cover image for Why Firestore Encourages Bad Security

Why Firestore Encourages Bad Security

Josh Brown on September 09, 2020

What is Firestore? Firestore is one of many products in the Firebase product line. Firestore is a document-based NoSQL database. Firebas...
Collapse
 
gautemeekolsen profile image
Gaute Meek Olsen • Edited

Well the flaws you mention are easily fixed with rules.

Only increment with 5 points

match /users/{id}{
  allow update: if request.resource.data.points - resource.data.points == 5 || !("points" in request.resource.data);
}
Enter fullscreen mode Exit fullscreen mode

The or operator is for when other properties than points are updated.

Prevent user from submitting the form multiple times

use batch in frontend:

const batch = db.batch();
batch.set(db.collection("form").doc("<id>"), formData);
batch.update(db.collection("users").doc("<userid>"), {has_filled_out_form: true});
batch.commit()
Enter fullscreen mode Exit fullscreen mode
match /form/{id} {
  allow write: if hasNotFilledForm() && hasFilledFormAfter();
}
function hasNotFilledForm(){
  return get(/databases/$(database)/documents/users/$(request.auth.uid)).data.has_filled_out_form == false;
}
function hasFilledFormAfter(){
  return getAfter(/databases/$(database)/documents/users/$(request.auth.uid)).data.has_filled_out_form == true;
}
Enter fullscreen mode Exit fullscreen mode

Conclusion

So I believe it boils down to knowing how to secure your data. I can easily create a server and a database and allow each request without writing any code for authentication, authorization, validation, etc. So the data can be both insecure and secure by using Firestore just the same as anything else.

Collapse
 
mysticza profile image
Chris Boik

You've nailed it on the head here.

The article fails to represent the power of security rules for validating user input and requests.

Your comparison to setting up a basic database logic layer is brilliant.

Collapse
 
jbis9051 profile image
Josh Brown

See my reply.

Collapse
 
jbis9051 profile image
Josh Brown • Edited

Thank you for your reply! You seem to be correct that those rules would work for the examples mentioned in this article.

However, I'd like to mention a couple of points to consider.

As your application starts to grow, if you implement all the necessary security rules (validation, authentication, authorization, logical checks, "batch checking", etc.), your firestore.rules will turn into a huge and messy and unmaintainable god file, making this solution not ideal for larger applications. Also, note that there are many limits on security rules. While those limits are pretty generous, it's worth considering when building larger applications, especially when considering the next couple of points. (Admittedly, this point is not directly related to security but it is still worth considering)

Additionally, as mentioned in the article, firestore security rules do not permit you to import libraries. This means you must either copy and paste source code for libraries you want to use or build a solution yourself. The "copy and paste" method exacerbates the "god file" and limits mentioned above. You must also keep up with updates to the library. The other option, not using a library, can be very dangerous. Most developers won't be able to implement let alone maintain their own implementation of security-related libraries (hence the need for the library in the first place).


I can easily create a server and a database and allow each request without writing any code for authentication, authorization, validation, etc. So the data can be both insecure and secure by using Firestore just the same as anything else.

Yes, you are correct. Anything can be implemented securely and insecurely. I'd like to explain why it's much easier to fail to implement firebase securely than a proper backend.

Most security issues relate to a set of wrong assumptions. Not checking for authentication is an assumption that the user is who they said they are. Not checking for authorization is an assumption that the user is allowed to do what they are trying to do. Poor validation is an assumption that the data the user submits is...well..valid.

All three of these specific assumptions aren't guaranteed in both firestore security rules and a classic server environment. This is we must implement checks to confirm that the user is in fact authenticated and authorized and the input data is valid.

However, there is a very important differentiator. Code written on the backend is guaranteed to run to completion without modification. This cannot be assumed to be true on the frontend, creating yet another layer of checks that needs to be implemented in security rules.

With the batch example from before, if implemented on a proper backend one can assume that both queries WILL run in the order you specified so there is no need to check that the second query will run.

The additional security rules you posted are needed because that same assumption cannot be made about code on the frontend. As you have proven with the fairly simple example of batch queries, it is possible add security rules to check this case but doing so adds another layer where developers who often are not great at security anyway, may make wrong assumptions and implement rules that don't fully check every possible situation.

Collapse
 
gautemeekolsen profile image
Gaute Meek Olsen

This was a good reply with some good points I missed in the article 😊👏

Collapse
 
bias profile image
Tobias Nickel

I also think, the pricing of the firestore is pretty fair, the pricing of cloud function is also pretty good, but as soon as you have to use multiple of these services, it adds up.

Thanks for sharing your thoughts and experiences, I think they will be useful in some discussions.

Collapse
 
jaredpotter profile image
Jared Potter • Edited

Great article Josh! You did a great job - I'm impressed. I also found it very useful with the project I'm currently working on.

One bit I'd like to suggest adding to your post is that Firestore Security Rules do allow for request sanitization. You mention sanitization once in reference to the logical layer but don't then mention that it is possible to prevent extra fields from being added to requests.

Here's a video at time that shows how to do it:
youtu.be/8Mzb9zmnbJs?t=1165

Collapse
 
patzistar profile image
Patrick Schadler

You're right, by removing the so called backend and putting all the logic in the presentation layer (aka frontend) you are removing a very important layer for security. Don't get my wrong I use Firebase and its services for basically all my private projects, but if you plan to go big you have to thing about this issues. A while ago I tried to put all the Firebase logic in a seperate backend service, but well, that's not what Firebase is for in the first place.

I think you have to find a compromise when you choose Firebase for your Application. Maybe you invest more time in Firebase Functions, but as you said, it's also a bit flawed.

Anyways, I believe we'll see more and more websites and apps which merely relies on such frontend sdks like Firebase in the future. Why? Because you only need to learn JavaScript/TypeScript and you are ready to build a whole application with authentication, data storage, user management and many more.

Collapse
 
jbis9051 profile image
Josh Brown

Don't get my wrong I use Firebase and its services for basically all my private projects, but if you plan to go big you have to thing about this issues. A while ago I tried to put all the Firebase logic in a seperate backend service, but well, that's not what Firebase is for in the first place.

Yes. I understand this. Firebase is pretty easy and simple, so for a private project where security is not a huge concern it maybe a great solution.

Because you only need to learn JavaScript/TypeScript and you are ready to build a whole application with authentication, data storage, user management and many more.

With the introduction of node, with only TypeScript/JavaScript, you can also achieve a proper backend server with all the things you mentioned. I hope that this will convince more users to create a proper backend, but I agree, due to firebase's ease it seems to be becoming more popular.

Collapse
 
zmandel profile image
Zig Mandel

other posters already mentioned that Rules fix the points mentioned. additionally you can use cloud functions for the cases where rules dont cut it. by no means you have to pick an all-or-nothing situation, which breaks your argument about making firestore pointless once you use cloud functions.
finally, there are still other advantages like reactive programming, which MongoDB doesnt give so its not a good replacement

Collapse
 
bscott profile image
Brian Scott

Thanks for the write up, I'm considering building a large app on top of firebase, everyone's comments are great and valid.

Collapse
 
jbis9051 profile image
Josh Brown

Awesome!

I encourage you to take a look at my comment in response to @Gaute Meek Olsenabove above. I think the points are worth considering especially for a larger application.

Collapse
 
bscott profile image
Brian Scott

My other fear is if I needed to move away from Firestore for any reason. Is that even possible as far as ease of mIgration to say MongoDB or FaunaDB..

Thread Thread
 
jaredpotter profile image
Jared Potter

Yes, you can write a node script w/ firebase admin to iterate over all documents in each collection and then call the appropriate mongoDB/faunaDB libraries to insert the records.

Although I'm not as familiar with it, you could also look into trying to extract the data from a Firestore backup file.

Collapse
 
tomlarkworthy profile image
Tom Larkworthy

the rules are the logic level, and you can't guarantee backend code is run to completion even in a three tier app if you consider distributed system faults.

Firestore can be coded securely and you get great performance if you eliminate a tier, of course, there are tradeoffs, but throwing a tool in the bin because it fails a specific use case is naive.

Collapse
 
jamesxabregas profile image
James Xabregas

A good post in terms of highlighting poor security practicies, although I had a read through that link to that article on The Register and what it is highlighting is actually about the Firebase Realtime Database, which is a different service.

Ultimately I think it is critical that developers understand the technologies they are using because you can build an insecure app on any stack. There were a lot of insecure LAMP stack applications too. I think the common element here is that technology stacks with a low barrier to entry attract a lot of inexperienced and self-taught developers and Firebase is attractive to that same crowd. An inexperienced developer is more likely to build an insecure app than an experienced developer. A lot of the issues you highlighted would be obvious to expereinced devs. It's an education issue, not a technology issue.