Your NodeJS App is Probably Vulnerable to NoSQL Injection Attacks

Who would have thought, right?

Berke Gökmen
3 min readAug 25, 2021
Image by Berke Gökmen

We all have watched numerous tutorials on building NodeJS apps using Express and MongoDB. That is, we know how to create one. However, most of us don’t know how to make them secure. If you are one of those people, you’ve come to the right article because you’re about to level up as a developer.

In this article, we will do the following:

  1. Build a simple NodeJS app
  2. Understand what a NoSQL Injection attack is
  3. Use a npm package to prevent attacks

Prerequisites

  • Basic knowledge about routing with express
  • Basic knowledge about using mongoose
  • Postman client (More info)

Database Setup

For this project, I assume that you have a ready-to-use MongoDB cluster or a local MongoDB installation and have the connection URI. If not, you can check these links for installation guides: Cluster, Local.

Project Setup

Let’s initialize our node app and install a couple of packages. Run the following commands in an empty folder.

npm init -y
npm i express mongoose
npm i nodemon dotenv -D

Create app.js and user.model.js.

We’re ready!

With the setup out of the way, let’s start by looking at a simple NoSQL attack.

For demonstration purposes, we will create a simple routes.js file.

Let’s make a GET request to /users to see what we have. As mentioned previously, we will be using Postman. Feel free to use any other REST client of your choice, though.

This is the response that the server returns. As seen from the code block above, we have three users (Passwords are shown for demonstration purposes).

Next, try to log in using one of the credentials. Make a POST request to /login with the request body below.

We get the following response. Everything seems pretty normal up to this point, so let’s look at some more exciting stuff!

It’s time to perform a NoSQL Injection 😈!

Firstly, what is NoSQL injection? NoSQL injection vulnerabilities allow attackers/users to inject code into commands for databases that use NoSQL queries rather than SQL, like MongoDB.

To perform a NoSQL injection attack, simply change the password value in the body from"123456" to { $ne: null }. So, the new request body looks like the following.

Wait… What’s happening here? What does the$ne operator do? Let me explain.

$ne operator tells mongo to check for not equal to. That is, instead of checking the password for the correct value, MongoDB will simply check whether the password field is null or not. Since the password field cannot be null in any case, we can trick MongoDB into giving us the user information without knowing the password.

After making a POST request to /login with the new modified request body, we get the following response from the server.

Congratulations, you have just logged in as test1 without even knowing the password! You might be asking; wow, is it this easy to do that?! The answer is yes, and there is more than one way to do the same thing. For instance, we could have used { $gt: "" } instead of $ne operator.

Fortunately, preventing this attack is as easy as performing it. Next, let’s take a look at how we can prevent NoSQL injection attacks.

NPM, the savior!

Here comes a package from npm, express-mongo-sanitize. Let’s start by installing the package, run the following command.

npm i express-mongo-sanitize

Now it’s time to look at what this package does for us. This npm package searches for anything suspicious, that is, keys starting with a $ sign or containing a .. MongoDB reserves $ and . to be used as operators.

Let’s use the package 📦!

Requiring the package returns a middleware function, which can then be used as in the example below.

This package also offers other ways to use it. You can check the full documentation here.

Congratulations!

You’ve learned about what a NoSQL attack is, how to perform one, and how to prevent it. Feel free to ask any questions in the comments, and do not forget to share your thoughts about this article. Hope it was helpful!

--

--