Basic Question About Security

I’m an admitted newb with Meteor. I have done a bit of research about security with my app. I am aware of some basic ways to make my app more secure. But my question is…how concerned do I need to be about security for an app that will be for private business use? It will be running online, but you need to log in to use it and only an Admin account can even create users. I’ve set up some allow and deny rules for inserting, updating, and deleting users. But is that enough until later when my project grows (I was planning on revisiting security when the app grows into an online store)?

edit: I would like to add that I’ve set up almost all of my inserts client side, which I just learned you shouldn’t do. Should I be particularly concerned about this?

Stay away from .allow and use method calls for any changes, so you can easily detect current user and approve/reject that change.
Anyone little more experienced in Meteor can ignore your client side security.

Thank you. So even if I have allow/deny rules (that I thought are pretty solid) they could still bypass this even if they are located in Meteor.isServer? So if I put my inserts in a method call I could add some custom security there and remove the other allow/deny completely?

Yes, allow/deny seems solid, but if you look deeper many times you will find a way how to trick them. Not avoid, just security gap you did not think of in time of implementation. Lets say it is not worth to dig deeper if you can easily use methods.

Thanks again. I think I will set aside a day to revisit my security then.

I really wish the “don’t use allow/deny” narrative would stop. Fact of the matter is that you can also easily leave a security hole using a method instead, the difference being that with a method it’s almost guaranteed to be written on both the client and the server and therefore easily inspected by a would be attacker. With allow/deny it can be defined in protected code only and still allow for latency compensation.

That being said… You really should not be using allow/deny for complicated write security. My recommendation is to learn how to use Collection2 with SimpleSchema and pair that with minor checks in allow/deny. For a good example have a look at the packages in the Socialize namespace. By using this technique you can achieve a high level of security and still keep all of the benefits Meteor offers, e.g. Latency compensation, and Database everywhere.

Thanks for your advice! I will look into Collection2 and SimpleSchema. One question though, what do mean by “minor checks in allow/deny”. Currently I use allow/deny to check simply is a user is logged in and if they are logged in, whether or not the user is admin. Would that be a minor check?

1 Like

Those are the kinds of checks that I’m referring to. Things like is the user allowed to update or delete a record, is there a logged in user… Nothing like is the value of a field in the proper format or even allowed in the document at all… Those things should be left to something like SimpleSchema.

1 Like

Well, I was refering to this kind of things
https://www.discovermeteor.com/blog/meteor-methods-client-side-operations/

Assuming that methods are used in server code and as the OP is having a login only application, here’s a question. When the login template is rendered the entire app is available in view-source (client code). In my previous PHP days, any login screen would limit what “includes” and other files that are needed for the app once logged-in, are actually available to a non-logged in user.

For example, in using SimpleSchema, that schema is available to the client, and thus it’s available to any non-belonging individual. I always thought that one’s database design/schema was to be a very protected asset.

So, are there any concerns here? If so are there any solutions?

Thanks.

PS. I’m about 3 weeks away from launching an MVP niche CRM app, and hosting my customer’s customer data is something that I want to keep safe from prying eyes.

1 Like

Learning to properly use SimpleSchema is the best possible way to protect your data from a write security perspective. I personally make heavy use of autoValue for any value that should not come from the client, and denyUpdate in cases where I want to allow updates but restrict which fields can be updated.

In the case of keeping users from seeing data they are not supposed to, this is a read security perspective and should be controlled through publications.

I understand the need for pubs/subs which will limit what data the user can “see.” Not having a black hat, isn’t just knowing how the database is schemed dangerous? Yes, server side checking and pattern matching is needed for all client input as is true an any language.

Any other thoughts or directions on how to best go about securing one’s app? Beyond the “remove autopublish”, use check(), and have all database interactions on the server-side, scrub all user input, etc?

Thanks.

I don’t see having your schema defined in shared space as a security hazard. SimpleSchema is simple enough to use that a setting up secure writes should not be an issue. As far as check goes, SimpleSchema takes care of this as well, you won’t need to use both. Also once you have a secure schema and some simple allow/deny to go along with it, client side operations are fine… Have a look at my Socialize-Friendships package for an example of secure collections with a 100% client side API

I agree that the allow/deny stigma is overblown. Mixing multiple allows with denies can sometimes be more work to reason about, but it’s not that much of a cognitive burden. Plus, packages like ongoworks:security help ease some of the pains.

As far as security goes, there are quite a few high level resources outlining best practices. My biggest suggestion is to thoroughly check every argument to each of your publications and methods. If you follow best practices and remember to never trust user input, you should be fine.

I talk about more specific security scenarios on my blog if you want to read more about that kind of thing.