How do you prevent NoSQL Injection?

In our previous example, our code was making the assumption that the user-provided username and hashedPassword were strings. We ran into trouble when a malicious user passed up a MongoDB query operator as their hashedPassword.

Speaking in broad strokes, NoSQL Injection vulnerabilities can be prevented by making assertions about the types and shapes of your user-provided arguments. Instead of simply assuming that username and hashedPassword were strings, we should have made that assertion explicit in our code.

Using Check

Meteor’s Check library can be used to make assertions about the type and shape of user-provided arguments. We can use check in our Meteor methods and publications to make sure that we’re dealing with expected data types.

Let’s secure our login method using Meteor’s check library:

    login(username, hashedPassword) {
        check(username, String);
        check(hashedPassword, String);
        return Meteor.users.findOne({ username, hashedPassword });

If a user passes in a username or a password that is anything other than a string, the one of the calls to check in our login method will throw an exception. This simple check stops NoSQL Injection attacks dead in their tracks.

Using Validated Methods

Meteor also gives us the option of writing our methods as Validated Methods. Validated methods incorporate this type of argument checking into the definition of the method itself.

Let's implement our login method as a validated method:

new ValidatedMethod({
    name: "login",
    validate: new SimpleSchema({
        username: String,
        hashedPassword: String
    run({ username, hashedPassword }) {
        return Meteor.users.findOne({ username, hashedPassword });

The general idea here is the same as our last example. Instead of using check, we’re using SimpleSchema to make assertions about the shape and types of our method’s arguments.

If a malicious user provides a username or a hashedPassword that is anything other than a string, the method will return an exception, preventing the possibility of NoSQL Injection attacks.