Core Enhancement for Security/Authentication


#1

I’m a complete novice to Meteor, so please take this opinion/idea with a grain of salt, and if it’s already available in some other form don’t shoot me. At the moment I am more comfortable programming in Assembly Language for an 8088 than I am meteor. A true dinosaur. Anyhow …

In the tutorial, the examples demonstrating the use of methods for Collection security shows:

Meteor.methods({
    addTask: function (text) {
    // Make sure the user is logged in before inserting a task
    if (! Meteor.userId()) {
        throw new Meteor.Error("not-authorized");
    }
    ...

It seems to me that a large percent of database interaction would desire to make sure a user is authenticated, and the application that I am working on will need to make heavy use of that fact before allowing database operations. It seems to me it would be super cool if Meteor could be extended with a core package (perhaps accounts:auth-collections?) such that you could do:

[Collection].authenticated.insert(...)
[Collection].authenticated.update(...)
[Collection].authenticated.upsert(...)
[Collection].authenticated.delete(...)
[Collection].authenticated.find(...)
[Collection].authenticated.findOne(...)

I think of this concept like a servlet filter, that fires before the servlet. (I warned ya, I’m a dinosaur) So these methods would fire and check for valid authentication before the existing database manipulation/retrieval methods are fired.

Seems to me it would be super cool if you could then do:

Accounts.authentication.config({
    unauthenticatedRoute: [some route]
});

as a one time setup, just like you might do an Accounts.ui.config( … ) call.

This is all off the cuff, but just thought I’d throw it out there.


#2

Hi Alfreema! welcome to the wondrous world of meteor :wink:
First of all it is best practice to do all database manipulation on the server. you can start those off using a Meteor.call().

for database manipulations you can use this: http://docs.meteor.com/#/full/allow
you will have to remove the insecure package for this to work

to limit which documents your client can find you can do some filtering in you publish methods like so : http://docs.meteor.com/#/full/meteor_publish

have fun :wink:


#3

Since when is it best practice to do all db manipulation on the server? I find collection2+simple-schema combined with allow/deny allows me to do all of my database operations on the client.


#4

I personally like to do all of my data manipulations inside Methods (which run on the server and client) so that I can have a clear API for my app - I know that if all of my methods are secure, then my whole app is secure because there would be no other way to write data to the database. I find it difficult to make sure that all of my allow/deny rules and schema validations are correct.

However, there are a lot of tools that will help you if you choose to take the alternate path of calling insert, update, and delete directly outside of methods. I think some of these do what the OP is looking for:

https://atmospherejs.com/aldeed/simple-schema
https://atmospherejs.com/aldeed/collection2
https://atmospherejs.com/alanning/roles

If anyone else knows some good validation/security automation packages, post them in the thread!


#5

It has been best practice to validate all client input at the server for ages.
Unless there is something I do not know this still applies to meteor


#6

He’s referring to this feature: http://docs.meteor.com/#/full/allow

It lets you do database operations on the client while still validating them on the server.


#7

I don’t think the issue really matters as to whether you are using Meteor.methods or not. Currently, even if you push the database operation into a Meteor.method block, it’s still going to allow you to perform the operation – unless you specifically check whether the person is authenticated – isn’t it? You can certainly restrict the allowed records to view (and I assume update) via publish, but what about preventing trash/spoofed inserts/upserts by an unauthenticated user?

Without adding repetitive extra code, like a user being authenticated or pushing an owner record into every collection, I am not sure you are preventing bogus records from being created by an unauthenticated user by only using publish/Meteor.method calls?