🚀 Invicti Acquires Kondukto to Deliver Proof-Based Application Security Posture Management
NoSQL injection is a vulnerability that lets a malicious hacker introduce (inject) undesired code into database queries executed by NoSQL databases.
Severity: |
![]() ![]() ![]() ![]() ![]() |
very severe |
Prevalence: |
![]() |
discovered rarely |
Scope: |
![]() |
may appear in NoSQL databases |
Technical impact: | database access | |
Worst-case consequences: | full control over the application | |
Quick fix: | fully dependent on the type of NoSQL database |
The term NoSQL (non-SQL or not only SQL) is used to describe non-relational databases in general and may refer to many different types of databases and data models, including key-value, key-document, column-family, and graph databases. NoSQL databases have rapidly gained popularity in recent years, with mainstream products such as MongoDB, Apache Cassandra, Apache HBase, Apache CouchDB, Neo4j, RavenDB, Redis, OrientDB, DynamoDB, HyperTable, Google Cloud Datastore, and many more.
NoSQL database engines use different data structures than relational databases and while they usually do not support SQL statements or SQL queries, they all provide ways for users to execute queries. Unlike with SQL databases, there is no common query language or syntax, so the query format depends on the specific database product and the implementation details of the web application or API. This means your queries will vary depending not only on the database but also on the programming language (e.g. Python, PHP, Node.js, etc.) and framework (e.g. Spring). Even so, most NoSQL queries are based on JSON, and they will often include user input. This means that – as always with unsanitized user inputs – NoSQL databases can also be vulnerable to injection attacks.
NoSQL injections don’t rely on a common query language, so a given injection vulnerability affects only one specific NoSQL database type. Apart from that, NoSQL injection attacks are similar to traditional SQL injection attacks – the attacker provides a malicious payload in user input, such as forms or HTTP requests, and if that input is delivered to the NoSQL database without sanitization, it may cause the database to execute commands supplied by the attacker.
To understand how a NoSQL query is constructed and where it may be vulnerable to an injection attack, we will focus on MongoDB as the most popular NoSQL database, accessing it using PHP. Here is a simple example that accesses a MongoDB database to perform authentication:
$username = $_POST['username'];
$password = $_POST['password'];
$connection = new MongoDB\Client('mongodb://localhost:27017');
if($connection) {
$db = $connection->test;
$users = $db->users;
$query = array(
"user" => $username,
"password" => $password
);
$req = $users->findOne($query);
}
As you can see, the username and password parameters used for authentication are taken from a POST request and then directly inserted into the query. Similar to other types of injection, this allows a malicious user to enter a NoSQL injection payload that provides unauthenticated access.
To perform a successful MongoDB injection, it could be enough to supply the following malicious input data in a POST request:
username[$eq]=admin&password[$ne]=foo
The [$ne] query operator means not equal, so the resulting query will find the first record where the username is admin and the password is not foo. If such code is used for authentication and the admin user exists, the attacker will be logged in as that user.
Other MongoDB operators can be abused in a similar fashion, for example, [$lt] and [$gt] as well as [$regex]. Using regular expressions in the above scenario, attackers might even be able to enumerate all users by trying various combinations in sequence and evaluating the results.
MongoDB queries commonly include the $where operator, which introduces possibilities of serious NoSQL attacks that include JavaScript objects. For example, a developer might want to use the $where operator in the following way to access a record for a particular user:
$query = array('$where' => 'this.name === \''.$name.'\'');
In this case, an attacker could use the following empty string comparison trick by injecting into $name:
'; return '' == '
As a result, the query will become:
"$where": "this.name === ''; return '' == ''"
Because the result is always true, the attacker will receive the entire list of users.
The $where operator is actually evaluated as JavaScript code, so the attacker could also pass a parameter with a malicious string that includes arbitrary JavaScript, for example:
'; while(true){}'
This example creates an endless loop that results in a denial of service attack.
NoSQL injection attack consequences depend on the database type and the way database communication is implemented. The attacker might bypass authentication, extract data, modify data, or even gain complete control over the web application. As a result, they may even be able to access the underlying operating system and gain control over the web server.
The best way to detect NoSQL injection vulnerabilities varies depending on whether they are already known or unknown.
To prevent NoSQL injections, you must follow general cybersecurity best practices and always treat user input as untrusted. Here are some general user input validation tips for all NoSQL databases:
Unlike many other web vulnerabilities, NoSQL injections can be caused not only by insecure web application code but also by vulnerabilities in NoSQL databases themselves. To improve mitigation, you should always use the latest versions of NoSQL databases, especially since some products, including MongoDB, were in the past known to have serious vulnerabilities.
Note that since NoSQL databases are a much more recent technology compared to SQL databases and there are also many different types to choose from, the potential for developer error is much higher. To minimize risk, make sure to always follow the principle of least privilege by running your application with the lowest privileges possible. That way, even a successful attack will not provide access to other server-side resources.
Classification | ID |
---|---|
CAPEC | 676 |
CWE | 943 |
WASC | 19 |
OWASP 2021 | A3 |
NoSQL injection is a vulnerability that lets a malicious hacker introduce (inject) undesired code into database queries executed by NoSQL databases such as MongoDB, Cassandra, Neo4j, Redis, and more.
NoSQL injections may allow the attacker to bypass authentication, extract data, modify data, or even gain complete control over the web application. As a result, malicious actors may even be able to access the underlying operating system and gain control over the web server.
Read an interesting post on the Shodan blog about the security of NoSQL databases.
To prevent NoSQL injections, follow general cybersecurity best practices and always treat user input as untrusted. Use input sanitization libraries available for many NoSQL products, including MongoDB.
Learn about the importance of input validation, not just for NoSQL injections.