Injection Attacks: SQL, Command, and LDAPLesson 2.2
How to prevent NoSQL injection in MongoDB queries
NoSQL injection mechanics, MongoDB operator injection, $where operator risks, express-mongo-sanitize, input type validation, Mongoose schema enforcement
NoSQL Injection in MongoDB
NoSQL databases like MongoDB are not immune to injection. Instead of SQL syntax, attackers inject MongoDB operators as JSON properties. If your application passes request body objects directly into queries, an attacker can manipulate query logic.
The Vulnerable Pattern
// Request body: { "username": { "$gt": "" }, "password": { "$gt": "" } }
// If you do this:
User.findOne(req.body); // Attacker bypasses login entirely
// Or this:
User.findOne({ username: req.body.username, password: req.body.password });
// Same problem — username and password can be objects with operatorsFix 1: Sanitize Incoming Objects
const mongoSanitize = require('express-mongo-sanitize');
// Strips keys starting with $ or containing .
app.use(mongoSanitize());
// Or replace with underscore instead of removing
app.use(mongoSanitize({ replaceWith: '_' }));Fix 2: Validate and Type-Assert Inputs
// Ensure inputs are strings, not objects
const { username, password } = req.body;
if (typeof username !== 'string' || typeof password !== 'string') {
return res.status(400).json({ error: 'Invalid input type' });
}
User.findOne({ username, password });The $where Operator
Never use MongoDB's $where operator with user input. It evaluates JavaScript on the server and is a direct code injection vector. It's also slow. Use MongoDB's query operators instead. In Mongoose, you can disable it via schema options to prevent accidental use.
