← All fixes

Fix it

NoSQL injection in MongoDB — how to fix it

High severityCWE-943 (Improper Neutralization of Data Within Query Logic)

MongoDB queries are objects, so if you pass a raw request value straight into a query, an attacker can send an operator object instead of a plain value. A classic example turns a login check into one that always passes. The fix is to validate and cast inputs to the type you expect, so a value is always a value, never an operator.

Why it's a problem

If your login query is find({ user, password }) and the client can send { "password": { "$ne": null } }, the query matches any record with a non-null password, bypassing the check entirely. The same technique extracts data or alters query logic anywhere unvalidated request input reaches a query.

The pattern

// req.body can be { "password": { "$ne": null } }
const user = await User.findOne({
  username: req.body.username,
  password: req.body.password,
});

The fix

// force values to strings so operators can't be injected
const username = String(req.body.username);
const password = String(req.body.password);
const user = await User.findOne({ username, password });
// better: validate with a schema (zod, joi) before querying

Why AI tools write this

Passing req.body fields straight into a query is the most direct way to write the feature, and it works for normal string input. The operator-injection path only opens when an attacker sends a crafted object, which a happy-path test never does.

The quick fix

  • Cast request values to their expected primitive type before using them in a query.
  • Validate input with a schema library so only expected shapes reach the database.
  • Never pass a raw request object directly into a query filter.

Want to know if this pattern is already in a repo you shipped? Scan a public repo free, no account needed.

Scan a repo →
NoSQL Injection (MongoDB) — Why It Happens and How to Fix It: Prbl