Mitigating NoSQL Injection Attacks: Part 1

In this first part of a two-part post series, we’ll reconstruct a NoSQL injection and cover the basics of mitigating it. In the second part, we’ll look at Server-Side JavaScript and Blind Injection attacks against NoSQL databases.

If you’re not validating or escaping user-manipulated input properly, you may find malicious parties executing dynamic queries against your SQL and NoSQL databases.

The attack vector, however, differs due to differences between these two types of databases. For example, the following won’t affect NoSQL databases (even if the malicious user input hasn’t been sanitized/escaped):

db.users.findOne({username: username, password: password});

Similarly, if the attacker suspects that “admin” is valid for the SQL database, they could use the following for a username field:

admin’ — 

These examples are high-level illustrations of how an attacker can try to alter the original SQL query. But, because the query language structure of NoSQL databases (such as MongoDB) is different, these queries don’t have the same negative effects as they would with a SQL database.

The Anatomy of a NoSQL Injection

With a typical application, you can expect to receive a username/password combination either using an HTML’s form handler or via an AJAX call where the request sends the information as JSON. For an ExpressJS web application, you’ll need the following middleware for the latter type of requests:

app.use(bodyParser.json());
app.use(bodyParser.urlencoded());

To authenticate the user, the POST login route and request sent from the browser to the database would look something like:

app.post(‘/login’, function(req, res) {
User.find({ username: req.body.username, password: req.body.password }, function(err, users) {
res.status(200).send(users); });
});

The User model runs a query against the MongoDB database to match the username and password fields. These are populated in req.body as first-class citizens. Attackers could take advantage of the authentication matching logic and exploit MongoDB’s operators to return a valid user object:

{“username”:{“$gt”: “”}, “password”:{“$gt”: “”}}

Because req.body.username is set to the object {“$gt”: “”} (which isn’t a valid MongoDB operating for matching documents where the username field is populated), this works. You can validate this as follows:

curl -X POST -H “Content-Type: application/json” — data ‘{“username”:{“$gt”: “”} , “password”:{“$gt”: “”}}’ http://127.0.0.1:31337/login

NoSQL injection attacks can lead to the bypassing of user authentication mechanisms, but they can also be used to implement threats such as Denial of Service (DOS) attacks. For example, someone might inject complex RegEx/matching statements that result in CPU-hogging actions such as full table scans. There are also issues where the RegEx provided by the attacker matches many records, providing the attacker with the sensitive information they could later leverage.

Mitigating NoSQL Injection Attacks

To mitigate NoSQL injection attacks, you must either:

  1. Validate the user input
  2. Escape problematic entries provided by the user

You could also take advantage of libraries (like sequelize) that provide you with prepared statements you could include in your queries.

Let’s take a look at how we might fix the NoSQL injection vulnerability we demonstrated above:

app.post(‘/login’, function(req, res) {
  User.find({ username: String(req.body.username),
  password: String(req.body.password) },
  function(err, users) {
    res.status(200).send(users);
  });
});

If, however, our application expects username and passwords to be strings (and we only get string type data), then all is well. However, if someone provides an object, e.g., object {“$gt”: “”} and we try to cast the object as a string, then:

console.log(String({“$gt”: “”}));
// result is: ‘[object Object]’

There are many different ways to validate the user input and confirm that it’s the type we’re expecting. So, keeping track of how MongoDB queries are run with regards to the input they match is important.


Mitigating NoSQL Injection Attacks: Part 1 was originally published in ShiftLeft Blog on Medium, where people are continuing the conversation by highlighting and responding to this story.


*** This is a Security Bloggers Network syndicated blog from ShiftLeft Blog - Medium authored by Katie Horne. Read the original post at: https://blog.shiftleft.io/mitigating-nosql-injection-attacks-part-1-930756e30d52?source=rss----86a4f941c7da---4