ESLint InterlaceESLint Interlace
Plugin: mongodb-securityRules

no-operator-injection

ESLint rule documentation for no-operator-injection

📡 Live from GitHub — This documentation is fetched directly from no-operator-injection.md and cached for 6 hours.

Keywords: NoSQL injection, CWE-943, MongoDB, $ne, $gt, $or, operator injection, security

Detects MongoDB operator injection attacks where user input is passed directly as query values, allowing attackers to...

Detects MongoDB operator injection attacks where user input is passed directly as query values, allowing attackers to inject operators like $ne, $gt, $or to bypass authentication or exfiltrate data.

⚠️ This rule errors by default in the recommended config.

Quick Summary

AspectDetails
CWE ReferenceCWE-943 (NoSQL Injection)
OWASPA03:2021 - Injection
SeverityCritical (CVSS: 9.1)
CategorySecurity
ESLint MCP✅ Optimized for AI assistant integration

Rule Details

This rule specifically targets operator injection - a subset of NoSQL injection where attackers submit objects with MongoDB operators instead of expected primitive values.

Attack Scenario

// Expected: { username: "john", password: "secret123" }
// Attacker sends: { username: "admin", password: { "$ne": "" } }

// This query:
db.users.findOne({ username: req.body.username, password: req.body.password });

// Becomes:
db.users.findOne({ username: 'admin', password: { $ne: '' } });
// Matches admin user with ANY non-empty password - authentication bypass!

❌ Incorrect

// User input passed directly - vulnerable to operator injection
User.findOne({ email: req.body.email });
User.findOne({ password: req.body.password });
User.deleteMany({ userId: req.query.id });

✅ Correct

// Force value comparison with $eq
User.findOne({ email: { $eq: req.body.email } });

// Cast to primitive type
User.findOne({ email: String(req.body.email) });

// Validate input is not an object
if (typeof req.body.email !== 'string') throw new Error('Invalid input');
User.findOne({ email: req.body.email });

Known False Negatives

Object Spread

// ❌ NOT DETECTED - spreads entire body into query
User.findOne({ ...req.body });

Dynamic Property Access

// ❌ NOT DETECTED - dynamic key assignment
const query = {};
query[field] = value;

Aggregation Pipelines

// ❌ NOT DETECTED - complex pipeline structure
User.aggregate([{ $match: req.body.filter }]);

When Not To Use It

  • When using Mongoose schema with strict validation that rejects object values
  • When all input is validated through a strict JSON schema (e.g., Zod, Joi)
  • In test files with intentionally vulnerable patterns

References

On this page

No Headings