NoSQL Injection Vulnerability
In this blog, we will be discussing the NoSQL Injection Vulnerability and its exploitations scenarios.
Before getting into the details of NoSQL injections, let us first see the difference between SQL (Structured Query Language) and NoSQL (Not Only Structured Query Language) databases.
There are multiple NoSQL databases available in the market, such as
- Mongo DB
- Elastic Search
- AmazonDynamoDB
- HBase
- Cassandra, etc.
Mongo DB stores the document in a JSON object (JavaScript object notation), mainly used for document databases.
What is NoSQL Injection Vulnerability?
The NoSQL injection is a vulnerability that occurs due to improper input validation. It allows attacker users to view or change backend data to which they do not have access. It happens at the application layer, and successfully exploiting this vulnerability could allow an attacker to gain full access to the data present in the database. Also, an attacker could run malicious queries, which could hamper confidentiality, integrity, and availability of data present in the database.
Now let us explore NoSQL injection in detail. NoSQL injection vulnerability is much similar to the traditional SQL injection vulnerability.
NoSQL databases were created to eliminate SQL injection problems in SQL databases and were considered highly secure compared to SQL databases. However, an injection is still possible in the case of NoSQL databases due to misconfiguration and loopholes left open during the development phase. In this blog, we will be focusing specifically on Mongo DB.
Commonly used operators in NoSQL Injection Vulnerability
- $ne = Not equal to
- $eq = Equal to
- $gt = Greater than
- $lt = Less than
- $regex = Regular expression
- $in = Check if the required data is present in a data structure such as an array, etc.
Below mentioned is an example of the simple query used for the authentication process in Mongo DB.
db.user_auth.find({Username: username, Password: password});
The query shown above is used for authenticating a user. In this query, user input such as username and password is directly used without input validation, thus allowing an attacker to inject data structures such as arrays, etc., mongo DB operators instead of a valid username and password. This data is either sent using JSON object or URL parameter.
Below shown is the expected JSON object by the application:
{ Username: “username”, Password: ”password” }
JSON object after injecting authentication bypass NoSQL payloads:
{ Username: { $ne: ”” }, Password: { $ne: ”” } }
Request to the mongo DB could be sent in two ways:
- Using form URL encoding schema
In this case, the payload is injected along with parameter names within a data structure like an array containing operators inside it.
Example:
POST /login HTTP/1.1 Host: target.com Content-Type: application/x-www-form-urlencoded Content-Length: 27 user=admin&password[$ne]=
- Using JSON object
In the case of a JSON object, a payload can be inserted directly into the value field.
Example:
POST /login HTTP/1.1 Host: target.com Content-Type: application/json Content-Length: 38 { “username”: “admin”, “Password”: {'$ne': “”} }
Common NoSQL Injection Attack Scenarios:
- Data exfiltration
Data such as username, password, secrets, etc., could be easily gathered using the $regex operator.
$regex operator makes use of regular expression using which an attacker could quickly check the length of the data, check if the data starts with a particular character, etc.
Example: In this case, $regex is used to guess the find the length of the password if the username is admin.
POST /login HTTP/1.1 Host: target.com Content-Type: application/x-www-form-urlencoded Content-Length: 27 username[$ne]=admin&password[$regex]=.{5}
- Authentication Bypass
Below shown is the simple authentication bypass scenario in which the application is vulnerable to NoSQL injection.
The username is admin, and instead of a password, we are sending JSON object with $ne operator. $ne will return true since the password value is not null.
POST /login HTTP/1.1 Host: target.com Content-Type: application/json Content-Length: 38 {"username":"admin", "password": {"$ne": null}}
- Denial of Service Attack
In the backend $where the operator is used, injecting JavaScript code having infinite while loop as a user-supplied data will result in total CPU power consumption.
For more payloads for exploitation of NoSQL injection vulnerability, do check out this link.
Automated tools available for detecting and exploiting NoSQL injection vulnerability
- NoSQLMap
NoSQLMap is an open-source python tool designed for auditing and automating injection attacks. However, there is a default configuration weakness in NoSQL databases and web applications that can be exploited. This procedure is carried out by using NoSQL to clone data or disclose it from the database.
Demonstration of simple attack scenario by exploiting NoSQL injection vulnerability
For the demo purpose, we will be making use of the OWASP juice shop application. In this application, after the authentication, the user is allowed to submit a review for a product. Once the review is submitted, a user only has permission to edit his review, not the other reviews given by other users in the application. For example, in this application, the user has the email id test@nulltest.com.
- The user clicks on a product and submits the review, as shown below.
POC: User submits a review
- After submitting it, the user clicks on edit the make changes in the proposed review.
POC: Edit submitted a review and intercept the request
- Intercept the request after editing the review. Each review has a unique alphanumeric ID value.
POC: Intercept the edit request
- Remove the Id parameter and add a simple NoSQL injection payload. It will ensure that the ID supplied is not equal to the ID value specified, i.e., -1.
POC: Added NoSQL injection payload in the id parameter
- Refresh the web page. NoSQL injection payload executes and alters all the reviews submitted by all the users.
POC: All the submitted reviews changed to attacker-supplied review text
Mitigation
- User data must be validated appropriately by identifying malicious data, such as objects and arrays used to inject NoSQL databases to prevent NoSQL injection.
- Lastly, admins and developers need to consider the access rights that must be afforded to the applications. A wrong decision can mitigate the potential damage of NoSQL injection attacks or any other attacks.
- In mongo DB, don’t use where, MapReduce, or group operators with user input, because these operators allow the attacker to inject JavaScript, and the result can be dangerous.
Conclusion:
Attackers can now not only extract the data from the database but also execute code in the application. For example, perform denial of service attacks or even take control of the user’s system or server. These attacks are pretty dangerous as the developers often use NoSQL data stores for relational database products, increasing the risk of insecure codes. Therefore, the most optimum way to reduce the dangers of NoSQL attacks is to avoid using uncertain user inputs in the application code.
References:
- https://blog.websecurify.com/2014/08/hacking-nodejs-and-mongodb.html
- https://blog.websecurify.com/2014/08/attacks-nodejs-and-mongodb-part-to.html
- https://owasp.org/www-project-web-security-testing-guide/v42/4-Web_Application_Security_Testing/07-Input_Validation_Testing/05.6-Testing_for_NoSQL_Injection.html
Author,
Gaurish Kauthankar
Attack & PenTest Team
Varutra Consulting Pvt. Ltd.