Written by Pete Corey on Aug 31, 2015.

I’ve been shouting for months about the importance of checking your method and publication arguments. But what do I mean when I say that? Is checking your arguments as simple as throwing in a check(argument, Match.Any); statement and moving on with your life? Absolutely not!

Incomplete Checks

I frequently see people running incomplete checks against their method and publication arguments. Check out this quick example:

Meteor.methods({
  processEvent: function(event) {
    check(event, Object);

    // Do processing...
    
    Events.remove(event._id);
  }
});

The processEvent takes in an event object, does some processing on it, and then removes the event object from the Events collection. This is all fine and good. We’re even checking the event argument!

Unfortunately, we’re not checking event thoroughly enough. What would happen if a user were to run this code in their browser console?

Meteor.call("processEvent", {_id: {$ne: ""}});

{_id: {$ne: ""}} is, in fact, an object, so it slips past the check statement. Unexpectedly though, the _id within event is an object as well. After processing the event object, the processEvent method would go on to remove all events in the Events collection. Behold the dangers of incomplete checks!

A More Thorough Check

The solution to this issue is to more thoroughly check the event argument. If we’re expecting event to be an object, we want to make a type assertion (and sometimes even a value assertion) over each field in that object. Take a look:

Meteor.methods({
  processEvent: function(event) {
    check(event, {
      _id: String,
      // Check more fields here...
      // name: String,
      // data: {
      //   value: Number
      // }
    });

    // Do processing...
    
    Events.remove(event._id);
  }
});

By checking that the _id of the event object is a string, we can avoid potential NoSQL injections that could wreak havoc within our application.

Final Thoughts

Incomplete checks can take many forms, be it check(..., Object);, check(..., Match.Any);, check(..., Match.Where(...));, etc… Regardless of the form they come in, incomplete checks are all little flaws stitched together with good intentions.

Checking your arguments is vitally important for a huge number of reasons, but it’s important that you follow through completely with your good intentions. Stopping with incomplete checks can leave you with a false sense of security and a vulnerable application.

Always (thoroughly) check your arguments!