Menu Icon Close
App Development

Security in Meteor Js

September 17, 2015
By Barkat Dhillon
Reading Time: 3 minutes

MeteorJS has revolutionized how the real-time and reactive app should work. With minimal effort at developer end, app can be more interactive and fast.
But there is a perception that MeteorJS is not a secure framework. What attributes to this belief?

The very basic command to create a new app meteor create myApp creates a highly insecure execution environment due to inclusion of autopublish and insecure packages.

Let’s see what’s happening behind the scenes.


autopublish package mirrors the server side data at client side as such. It means client cache behaves like DB, all data sit there and all queries are run against it.



insecure package grants all the connected client to modify and delete any data in the database, just like running commands through server console.

Why Meteor add these data threats as default?

Answer is Ease to start and fast prototyping.

  • Frameworks take lot of time to setup and get the development up and starting.
  • Setting up database connection is time consuming and a tedious task
  • Code cannot be tested till the both client and server side code is ready

Adding autopublish and insecure packages greatly speed up the initial development phases.
Just running Books.find() will get the complete dataset at front side.
Also adding data to the database is easy. Just running Books.insert({name: ‘New Book’}) will add new data in database. Moreover, DB statements can be executed from the browser console as well, so the developer can get started without any UI.
So having these packages makes the client-side development as easy as server-side development.

Production Ready Applications

Fast and steady development is fine, but what about production applications. Applications cannot go-live if the end-user has access to all the restricted data along with access to modify it anytime.
That is simple too. Remove autopublish and insecure.
meteor remove autopublish
meteor remove insecure

Execute these two commands and whoosh.. now client can no longer access data by running Books.find() or Books.insert()
What essentially these two commands did was all the special privileges client had through these two packages, has been removed and now developer has to specifically publish the data client side should have access to as well as what kind of db access grants client can have.

Publish Data

Meteor publications come handy to publish data. Data can be published at server side while client can subscribe for the data it requires.
Like, to show the all the books on the page.

Server side:

Server should publish the dataset that client wants to consume:

Publish all books:

Meteor.publish(‘books, function(){
return Books.find();

Publish method can as well only publish the subset like,
Publish only books from a particular author:
Meteor.publish(‘booksByAuthor’, function(author){
return Books.find({author: author});

Client side:

Just publishing from server is not enough, client should know what data it requires and should subscribe to that.
Once subscribed, client can run the queries on local cache as earlier.

Grant Access

insecure provided full access to end-user but that’s not advisable. In ideal scenario, all db modification/deletion requests must go via server
Having said that, client side modifications make the application more responsive as data is first updated in local cache that immediately updates the client, while data is synced up with the backend.
If user has enough authorization to modify data, then client side modification access can be provided using Methods and Allow/Deny


Method can be defined at server side:
insertNewBook: function(title){
Books.insert({title: title});

Later invoked at client side:‘insertNewBook’,’My First Book’);
But Methods still don’t give the freedom of running queries on local cache. All such requests are routed via server. That’s where Allow/Deny comes into picture


Allow/Deny are the server-side callbacks that executes for insert, update and remove commands on database.
Operation is only permitted if either:

  • At least one allow callback returns true i.e. allow takes priority over deny.
  • No deny callback returns true.

Callbacks can be defined as below:
update: function(userId, doc){return true;}
insert: function(userId, doc){return false;}
remove: function(userId, doc){return false;}

Instead of simply returning true/false, some checks can be performed in callbacks to see if the user has adequate rights to run that command.
Like, only the author of the book must be able to update it.
update: function(userId, doc){return doc && doc.userId === userId;}
insert: function(userId, doc){return false;}
remove: function(userId, doc){return false;}


Invest in better
solutions today

Contact Us