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!