JavaScript NoSQL Injection prevention in MongoDB

Sushant's answer is not correct. You need to be aware of NoSQL injection in MongoDB.

Example (taken from here)

User.findOne({
    "name" : req.params.name, 
    "password" : req.params.password
}, callback); 

If req.params.password is { $ne: 1 }, the user will be retrieved without knowing the password ($ne means not equals 1).

MongoDB Driver

You can use mongo-sanitize:

It will strip out any keys that start with '$' in the input, so you can pass it to MongoDB without worrying about malicious users overwriting.

var sanitize = require('mongo-sanitize');

var name = sanitize(req.params.name);
var password = sanitize(req.params.password);

User.findOne({
    "name" : name, 
    "password" : password
}, callback); 

Mongoose Driver

As it follows a schema, if the password is a string field, it will convert the object { $ne: 1 } to string and no damage will be done. In this case, you don't need to sanitize, just remember to set a proper schema.


Although the post is obsolete, I'm answering.

I know three ways.

First: There is a multipurpose content-filter. Also provides MongoDB injection protection by filtering way.

Second: mongo-sanitize, Helper to sanitize mongodb queries against query selector injections.

Third: I'd seen over here this solution which can be applied for MongoDB too. It's really simple to implement. Only use built-in escape() function of JavaScript.

escape() converts the string into ascii code. $ne is converted into %24ne.

var privateKey = escape(req.params.privateKey);

App.findOne({ key: privateKey }, function (err, app) {
  //do something here
}

In order to guard against query selector injections from a data object with unknown structure

Use mongo-sanitize to deeply sanitize via recursion:

const deepSanitize = (value) => {
    if(Array.isArray(value)){
        value.forEach(elm=>deepSanitize(elm))
    }
    if(typeof(value) === 'object' && value !== null){
        Object.values(value).forEach((elm)=>{
            deepSanitize(elm)
        })
    }
    return sanitize(value)
}

For example with sanitize(req.query) nested query selectors will not be removed:

const req = {} 
req.query = { _id : { $ne: 1 } } 

console.log(req.query))               // { _id: { '$ne': 1 } }
console.log(sanitize(req.query))      // { _id: { '$ne': 1 } }

Using deepSanitize(req.query) sanitized objects (including nested) are mutated:

console.log(deepSanitize(req.query))       // { _id: {} }
console.log(req.query)                     // { _id: {} }

Eliminate object mutation with {...req.query}:

console.log(deepSanitize({...req.query}))  // { _id: {} }
console.log(req.query)                     // { _id: { '$ne': 1 } }