Skip to content
العربية

NoSQL Injection

When JSON values flow into a document-database query as operators — bypassing login, defeating operator blacklists, and leaking data one character at a time.

Estimated time
25 min
Level
Intermediate
Your progress in this track0%

Before this lesson

NoSQL databases (MongoDB and friends) query with structured objects, not a string language. That removes the classic SQL quote-breaking — but opens a new door: if user-supplied JSON flows into the query filter without a type check, the attacker can send an operator object where the app expected a plain value, and change what the query means.

What is the vulnerability?

A login builds its filter straight from the request body:

login.js
const user = db.users.findOne({ username: req.body.username, password: req.body.password });

If password arrives as the string "guess", it is compared for equality. But if the client sends {"password": {"$ne": null}}, the value is an operator that matches any password — login bypassed, no secret needed.

Why does it happen?

The app assumed every JSON value is a string. JSON can also carry objects, and the query layer treats a $-prefixed key as an operator. Trying to fix it by banning $ne is a blacklist: $gt, $in, $regex all remain, and $regex even turns a yes/no login into an oracle that leaks the stored value one character at a time.

How do you stop it?

Type-check every value before it reaches the query: a credential must be a string, never an object. Compare passwords against a stored hash, not a live value. Do not chase operators one by one — reject the wrong shape outright.

The three labs below are exactly this ladder: an operator login bypass, a $ne blacklist beaten by $gt, and blind $regex extraction of the admin password.

Labs

  • Operator login bypass

    EasyBrowser lab

    Sign in as admin without its password, using a NoSQL operator.

  • An operator blacklist

    MediumBrowser lab

    Sign in as admin using an operator other than ne.

  • Blind regex extraction

    HardBrowser lab

    Extract the full admin password via regex, then submit it.