tommyd456
tommyd456

Reputation: 10683

MongoDB injection attack prevention

Looking at preventing injection attacks on my MongoDB which my API uses.

Private Keys are sent to the API and the API checks to see if the private key exists in the DB:

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

Is a simple search like this (I'm using Mongoosejs) vulnerable to injection attacks? I've read that use of $where can be but not sure whether I need to do anything here to prevent malicious activity.

Any advice would be much appreciated.

UPDATE: After a little more reading I've changed my query to the following:

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

Is this an improvement?

Upvotes: 3

Views: 3557

Answers (3)

efkan
efkan

Reputation: 13217

Actually there are several solution for MongoDB.

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

Second: 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({ privateKey: privateKey }, function (err, app) {
  //do something here
}

Actually a similar question had been asked over here.

Upvotes: 0

Zanon
Zanon

Reputation: 30760

As the Mongoose driver follows a schema, you just need to set the privateKey to be a string field. If someone passes an object like { $ne: null }, Mongoose will convert it to string and no damage will be done.

Note: { $ne: null } means not equals null that would retrieve the first result without knowing its key.

Another option is to sanitize the inputs before using them. For this task, 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 privateKey = sanitize(req.params.privateKey);

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

Upvotes: 1

wdberkeley
wdberkeley

Reputation: 11671

It's vulnerable to some injection attacks if you do not enforce the type of the privateKey variable, for example, if someone sent you the private key { "$gte" : "abracadabra" }, the query could return a document that the client is not supposed to access. Enforcing the type of privateKey as String should be sufficient to guard against simple injection attacks.

Upvotes: 5

Related Questions