最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

How to prevent invoking 'Meteor.call' from JavaScript Console? - Stack Overflow

programmeradmin4浏览0评论

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?

Share Improve this question asked Feb 1, 2016 at 2:17 TeerasejTeerasej 1,5365 gold badges21 silver badges32 bronze badges 3
  • 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 the insecure 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
Add a ment  | 

5 Answers 5

Reset to default 2

Meteor.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.

  1. 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
  2. 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/
  3. Remove packages insecure and autopublish

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

发布评论

评论列表(0)

  1. 暂无评论