I just noticed that Meteor.call
, the concept that prevent user from invoke collection's insert, update, remove method, still able to be invoked from JavaScript console.
For client's example:
// client
...
Meteor.call('insertProduct', productInfo);
...
Here's the server part:
// server
Meteor.methods({
insertProduct: function( productInfo ){
Product.insert(...);
}
})
OK, I know people can't invoke Product.insert() directly from their JavaScript console.
But if they try a little bit more, they'd find out there's Meteor.call()
in client's JavaScript from Developer tool's resource tab.
So now they can try to invoke Meteor.call
from their console, then try to guessing what should be productInfo
's properties.
So I wonder how can we prevent this final activity?
Does Meteor.call
done the job well enough?
or I'm missing something important?
I just noticed that Meteor.call
, the concept that prevent user from invoke collection's insert, update, remove method, still able to be invoked from JavaScript console.
For client's example:
// client
...
Meteor.call('insertProduct', productInfo);
...
Here's the server part:
// server
Meteor.methods({
insertProduct: function( productInfo ){
Product.insert(...);
}
})
OK, I know people can't invoke Product.insert() directly from their JavaScript console.
But if they try a little bit more, they'd find out there's Meteor.call()
in client's JavaScript from Developer tool's resource tab.
So now they can try to invoke Meteor.call
from their console, then try to guessing what should be productInfo
's properties.
So I wonder how can we prevent this final activity?
Does Meteor.call
done the job well enough?
or I'm missing something important?
- 3 There is nothing, nothing, a JavaScript program can do that you can't replicate in the console. Nothing. The only thing to do is have airtight validation on serverside, so that only the things you expect to go through go through. – Amadan Commented Feb 1, 2016 at 2:21
-
also, in case it's not yet clear from Amadan's ment, yes users can call
Product.insert()
from the console. So you need to make sure you have the right allow/deny rules in place on the server (and have removed theinsecure
package). – Christian Fritz Commented Feb 1, 2016 at 3:06 -
There is nothing wrong with this. Every application on the web has some kind of
Meter.call
, usually it's just an ajax call to some URL, so you can open console and make ajax calls, that's OK. Just don't trust the client. – imkost Commented Feb 1, 2016 at 3:28
5 Answers
Reset to default 2Meteor.call is a global function, just like window.alert()
. Unfortunately, there is nothing you can do from preventing a user calling Meteor.call. However, you can validate the schema of data and the actual data of what a user is sending. I'd remend https://github./aldeed/meteor-simple-schema (aldeed:simple-schema as the meteor package name) to ensure you don't get garbage data in your project.
As others pointed out, "Meteor.call" can surely be used from the console. The subtle issue here is that there could be a legal user of a meteor app who can in turn do bad things on the server. So even if one checks on the server if the user is legal, that by itself does not guarantee that the data is protected.
This is not an issue only with Meteor. I think all such apps would need to potentially protect against corruption of their data, even through legal users
One way to protect such corruption is by using IIFE (Immediately Invoked Function Expression)
Wrap your module in a IIFE. Inside the closure keep a private variable which stores a unique one time use key (k1). That key needs to be placed there using another route -- maybe by ensuring that a collection observer gets fired in the client at startup. One can use other strategies here too. The idea is to squirrel in the value of k1 from the server and deposit it in a private variable
Then each time you invoke a Meteor.call from inside you code, pass k1 along as one of the parameter. The server in turn checks if k1 was indeed legal for that browser connection
As k1 was stored inside a private variable in the closure that was invoked by the IIFE, it would be quite difficult for someone at the browser console to determine the value of k1. Hence, even though "Meteor.call" can indeed be called from the browser console, it would not cause any harm. This approach should be quite a good deterrent for data corruption
As mentionned by @Faysal, you have several ways to ensure your calls are legit. An easy step to do so is to implement alanning:roles
and do role checks from within your method like the following:
Meteor.methods({
methodName: function() {
if (!Roles.userIsInRole(this.userId, 'admin')) {
throw new Meteor.Error(403, 'not authorized);
} else { yourcode });
This way, only admin users can call the method.
Note that you can also check this.connection
from within the method and determine if the call es from the server (this.connection === false
) or from the client.
Generally speaking, doing checks and data manipulations from your methods is a nice way to go. Allow/deny are nice to begin with but bee really hard to maintain when your collections get heavier and your edge-cases expand.
You cannot block Meteor.call
from the console, just like you can't block CollectionName.find().count()
from the console. These are global functions in meteor.
But there are simple steps you can take to secure your methods.
- Use
aldeed:simple-schema
to set the types of data your collection can accept. This will allow you to set the specific keys that your collection takes as well as their type (string, boolean, array, object, integer) https://github./aldeed/meteor-simple-schema - Ensure that only logged in users can update from your method. Or set global Allow/Deny rules. https://www.meteor./tutorials/blaze/security-with-methods && https://www.discovermeteor./blog/allow-deny-a-security-primer/
- Remove packages
insecure
andautopublish
The simple bo of schema and allow/deny should do you just fine.
As you know by now that you can't really block calling Meteor.call
from Javascript console, what i'd like to add as a suggestion with @Stephen and @thatgibbyguy that, be sure to check your user's role
when adding documents into the collection. Simple-Schema
will help you prevent inserting/updating garbage data into the collection. and alanning:roles
package certainly makes your app secure by controlling who has the permission to write/read/update your collection documents.
Alanning:roles Package