Asad

ASAD

No SQL Injection – Portswigger: Exploiting NoSQL operator injection to bypass authentication

Introduction

NoSQL databases power a huge chunk of modern web apps — from user profiles and session stores to search engines and analytics. Unlike relational databases, many NoSQL systems (MongoDB, CouchDB, Elasticsearch, Redis, etc.) accept JSON-like query objects instead of SQL text. That flexibility makes development fast, but it also changes the attack surface: if your application builds queries from untrusted JSON input, an attacker can alter query logic and get results the developer never intended.

In this post you’ll learn why NoSQL injection is a real and practical threat, see conceptual examples of how operator objects like $ne, $in, and regexes can change query semantics, and get a clear, defensive checklist you can apply right away. This is a defensive, educational write-up — examples are conceptual and intended for authorized testing only. By the end you’ll understand the root cause, how to detect suspicious query shapes, and how to harden your app so JSON inputs can’t be weaponized against you.

How NoSQL injection works — the mechanics (copy-paste)

NoSQL injection occurs when untrusted JSON input is treated as part of a query object instead of plain data. In many NoSQL systems queries are JSON-like objects; if an attacker can supply values that are objects (not primitives), those objects can contain query operators that change the meaning of the query.

Below are common operator classes and why they matter:

  • $ne (not equal) — Normally username == "alice". But if the value becomes { $ne: null }, the comparison is no longer checking for equality; it matches any document where username is not null. In auth flows this can turn an exact-match check into a presence check and bypass authentication logic.
  • $in (in array) — Intended to test membership in a known set. When an attacker supplies an array or $in fragment where a single value is expected, the database may accept any of several values, widening the match set.
  • Regex matching ($regex) — Exact string matches become pattern matches. If user input is interpreted or injected as a regex, it may match far more documents than intended (especially with loose patterns or case-insensitive flags).
  • $where / server-side JavaScript — Some engines allow injected expressions or JS; these are effectively code-execution inside queries and are extremely dangerous. Disable or avoid $where in production.

Tools

Methodology

NoSQL injection occurs when an attacker manipulates queries by injecting malicious input into a NoSQL database query. Unlike SQL injection, NoSQL injection often exploits JSON-based queries and operators like $ne$gt$regex, or $where in MongoDB.

Operator Injection

Operator Description
$ne not equal
$regex regular expression
$gt greater than
$lt lower than
$nin not in

Challenges

The login functionality for this lab is powered by a MongoDB NoSQL database. It is vulnerable to NoSQL injection using MongoDB operators.

To solve the lab, log into the application as the administrator user.

You can log in to your own account using the following credentials: wiener:peter.

Walkthrough

Step 1 – The client sends a JSON-formatted login request containing username and password. we know that application is using mongo DB

Step 2- To assess whether the application improperly interprets JSON values as query fragments, we examined behavior related to the $ne operator. The $ne operator means “not equal”; when present as a query fragment it changes the comparison semantics rather than acting as a plain string.

The screenshot below shows the test condition and the application’s response, indicating the database accepted the operator-form value and the request was processed.

Step 3- Next, we tested the same request using the correct password within an operator-style value. The server responded with 200 OK and displayed the usual “invalid username or password” message. This shows that the backend is parsing the JSON input as query logic instead of plain data — confirming a NoSQL injection risk.

Step 4-We tried the administrator username as part of the challenge. The login attempt failed and the server returned an error.

Step 5- Now we test the $in operator. In MongoDB, $in lets you give a list of possible values, and the query returns true if any one of them matches.

So, we created a small list of usernames that included “administrator” and sent it in the request. This helps us see whether the application accepts multiple usernames at once. The request went through, but the login still failed — meaning the app didn’t authenticate even when “administrator” was part of the list.

Step 6- To confirm whether our payload actually works, we add the username in the list with “wiener”, which is a valid user in this lab. This time, the login was successful — showing that our payload structure is valid and the $in operator is being processed correctly by the backend.

Step 7- Next, we tried the $regex operator — one of the most powerful (and risky) operators in MongoDB. It allows pattern matching, which means it can log in a user if even part of the username matches a pattern. To test this, we used the pattern ^w, which matches any username starting with the letter “w”. Since the valid user “wiener” begins with “w,” the application successfully logged that user in.

Step 8-In the same way, we used the $regex operator again — this time with the pattern ^a, to match any username starting with the letter “a.”

And boom 💥 — we got logged in as the administrator, whose actual username was admin22h3vv9x. This confirms that the $regex operator can be exploited to bypass authentication completely.

We successfully solve the lab challenges

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top