NoSQL databases are becoming quite popular due to their advantage over SQL databases in scalability and easy-to-use schema. With the introduction of a new database, a new kind of attack has also been developed – NoSQL injection.
Additionally, a database is used to organize and store data electronically in a computer system and is controlled by Database Management System known as DBMS. DBMS allows users and applications to perform several operations on a system using SQL.
SQL stands for Structured Query Language; it is a programming language developed by IBM in 1970 and was commercially made available in 1979. Since then, SQL databases have become an integral part of building web applications. It is also known as a global standard for RDBMS (Relational Database Management System), where-in relational databases are used to store data in tables, and SQL is used for accessing and manipulating them.
There are also some security concerns related to using SQL queries and databases. A small example of such vulnerability could be found in this SQL injection in the school management system report.
However, with the growth of the Internet, applications became bigger and started having scalability issues with SQL. That’s when NoSQL came into the picture in 1998.
NoSQL databases are non-tabular, which means they can store data in formats other than the traditional table structure. The main types of NoSQL databases are document, key-value, wide-column, and graph. They provide flexible schemas that can be scaled easily.
Additionally, NoSQL injection is a vulnerability in an application where the attackers can craft a malicious query to attack the database being used in the application.
NoSQL injection can also lead to the attacks such as:
- Bypassing authentication
- Exfiltrating sensitive data
- Tampering with the data on the database
- Compromising the database or even the server
There are a few open-source tools that can be used to automate the process of detecting NoSQL injection, which are:
There are many NoSQL databases used today, among which the most common ones are- MongoDB, Redis, Apache Cassandra, DynamoDB, etc. MongoDB is one of the widely used NoSQL databases because the security issues related to NoSQL injection are pre-identified in it.
So, here we are focusing on another popular NoSQL database – Redis and its NoSQL vulnerability that leads to parameter overwrite of Redis keys.
NoSQL Database: Redis
Redis stands for remote dictionary server. It is an in-memory key-value data structure store that can be used as a database, cache, and message broker.
Data can be stored in Redis in multiple ways. It can be a key value system or a key field value system. When there is a need to store more than one data, we can use the later system, which is the key field value.
Setting up the application with NoSQL Injection vulnerability
Application is created using Node.js along with Redis as the database. Redis software is installed in the system to connect to the application. The server works on port 6379 by default.
In the Application:
A promise in Node means an action that will either be completed or rejected. In case of completion, the promise is kept, and otherwise, the promise is broken. And unlike callbacks, promises can be chained.
The async keyword gives you a simpler way to work with asynchronous promise-based code. Adding an async keyword at the start of a function makes it an async function. Inside an async function, you can use the await keyword before a call-to-a-function that returns a promise. This makes the code wait at that point until the promise is settled, and the fulfilled value of the promise is treated as a return value, or the rejected value is thrown.
Promise notify whether the request is fulfilled or rejected. Callbacks can be registered with the .then() to handle fulfillment and rejection. The .then() can be chained to handle the fulfillment and rejection, whereas .catch() is used for handling the errors (if any).
The application contains a webpage to enter user details stored in the Redis database. The username is treated as the key, and the name, password, and description are stored as field and value data. There is a ‘role’ field that is also set by the server with a default value of ‘user.’ The page has the feature to retrieve user details through a username. The aim is to enter new user data in the Redis database, where the user is stored with an ‘admin’ role.
- To start the Redis server, go to the Redis folder and type the following command on the terminal:
- To start Redis CLI, go to the Redis folder and type the following command on the terminal:
- To start the node application, go to the application folder and type the following command on the terminal:
NoSQL injection is demonstrated at the user details extraction and login page. Redis server must be started to get the database running and for the application to work. After that, the Redis CLI is used to check or manipulate the data stored in the Redis database.
User data is entered normally into the input fields, and the request is intercepted in Burp Suite. The request in Burp Suite is modified such that the username field contains a JSON value, including all the field parameters as keys and their values as responses. In addition, a ‘role’ field is added to the JSON value, with ‘admin’ being its value.
There is a Parameter Overwrite Injection vulnerability in the Redis module for Node.js. In this type of injection, the user can input an array in the input data containing the key and values of different fields, and it will overwrite the complete data.
In case of data being parsed as JSON, the payload needs to contain a JSON type of value instead of an array. In case a hidden field is set on the server side, just by knowing the field name, the user can input the value for it in the input. The same user input value will be reflected in the hidden field, while the server-side default value for it will be ignored.
If the comma-separated values are given as an array to the SET function in the Redis query, those values are treated as key and value pair. The other value, which is explicitly defined for the array keys, is ignored.
This functionality is available in the SET function in Redis version 3.1.2 and below. From version 4.0.0, Redis uses HSET for setting multiple values, and the parameter overwrites injection is no longer possible.
The original request looks like:
The modified request(payload) looks like:
The ‘redis’ library is vulnerable to this parameter overwrite injection vulnerability till version 3.1.2, and from version 4.0.0, and this vulnerability cannot be reproduced. The version of the ‘node-redis’ library used in the application can be changed by entering the version in the package.json file. The command ‘npm install’ will update the complete node library with respect to the libraries and their versions in the package.json file.
NoSQL injection in Version 2.6.1
NoSQL injection in Version 4.0.0
The previous examples show the vulnerability in some of the previous versions of Redis module in a Node.js application. The recent versions of Redis module have the vulnerability resolved by the introduction of new functions for setting and fetching data; still, some legacy applications are commonly found to be using components with vulnerable versions. So, the need to keep on updating the application with the introduction of the new patch and new versions of components in use becomes important.
Contributor: Prajyot Chemburkar