Zennoxa Shield
Rules / JavaScript / TypeScript
SHIELD-JS-020

NoSQL injection via user-controlled query object

highJavaScript / TypeScriptCWE-943CVSS 8.1

What it detects

Passing req.params/query/body straight into a Mongo query lets an attacker inject operators ($ne, $gt, $where) to bypass auth or exfiltrate data.

How to fix

Cast/validate user input to the expected scalar type before using it in a query; reject object-valued fields where a string is expected.

Vulnerable — Shield flags thislogin.js
const express = require('express');
const app = express();

app.post('/login', (req, res) => {
  User.findOne({ username: req.body.username, password: req.body.password })
    .then(user => res.json({ ok: !!user }));
});
Fixed — scans cleanlogin.js
const express = require('express');
const app = express();

app.post('/login', (req, res) => {
  const username = String(req.body.username);
  const password = String(req.body.password);
  User.findOne({ username: username, password: password })
    .then(user => res.json({ ok: !!user }));
});

Both snippets are verified against the shipped scanner: the vulnerable one triggers SHIELD-JS-020, the fixed one does not.

SHIELD-JS-020: NoSQL injection via user-controlled query object — Zennoxa Shield