SQL Injection vs NoSQL Injection

Same concept, different databases. The payloads change but the root cause is identical.

SQL InjectionNoSQL Injection
Target databasesMySQL, PostgreSQL, MSSQL, Oracle, SQLiteMongoDB, CouchDB, Redis, Elasticsearch
Query languageSQLJSON objects, JavaScript, custom query syntax
Classic payload' OR 1=1--{"$gt": ""} or {"$ne": null}
Injection pointString concatenation in SQL queriesObject injection in query filters
Data exfiltrationUNION SELECT, blind techniquesOperator abuse ($regex, $where), blind techniques
DefenseParameterized queries / prepared statementsInput type validation, avoid $where, use ODM safely
ToolingsqlmapNoSQLMap, manual testing

The short answer

Both are injection: user input is interpreted as query structure instead of query data. The difference is what the structure is made of. SQL injection manipulates a text query language. NoSQL injection usually manipulates an object or document — which means the payload is often a JSON type rather than a string, and the defenses that stop SQL injection don't automatically apply.

How to tell which problem you have

Ask what the driver receives. In SQL the application almost always builds a string and hands it to the database. In MongoDB and similar document stores the application builds a structure — a dictionary, a BSON document — and the injection point is frequently the ability to substitute an object where the developer expected a scalar. This is why {"$ne": null} works where ' OR '1'='1 would in SQL: you aren't breaking out of a string, you're changing the type of a field.

Ask whether the language has a server-side execution path. Some NoSQL databases will evaluate expressions or JavaScript — MongoDB's $where and mapReduce historically, and several key-value stores have scripting features. Where those are reachable with user input, the ceiling is higher than classic SQL injection because you may be running code rather than querying.

Ask where the input crosses from untyped to typed. This is the practical detection heuristic for NoSQL injection. A JSON request body preserves types, so a client can send an object where a string was expected. A URL-encoded form usually doesn't — unless the framework's parser supports bracket notation, in which case user[$ne]= reconstructs the object anyway. Express with qs, and PHP's array parsing, both do exactly this, and it surprises people every time.

Worked example: the same authentication bypass, twice

A login handler looks up a user by the supplied username and password.

SQL version. The query is built by concatenation: SELECT * FROM users WHERE user='$u' AND pass='$p'. Sending ' OR '1'='1' -- as the username terminates the string literal, injects a tautology, and comments out the rest. The database is handed a different query than the developer wrote. The fix is a parameterized statement, which sends the query and the values separately so no string the user controls can become syntax.

NoSQL version. The query is built as a document: db.users.findOne({user: u, pass: p}). Nothing is concatenated and there is no string to escape — yet sending a JSON body of {"user":"admin","pass":{"$gt":""}} logs in as admin, because pass is now an operator document meaning "any value greater than the empty string" rather than a literal. The fix isn't escaping either; it's ensuring pass is a string before it reaches the driver, by schema validation or an explicit cast.

Same outcome, same root cause, completely different remediation — which is why "we use MongoDB so we don't have SQL injection" is a category error rather than a defense.

Tooling and testing

SQL. sqlmap is the reference tool and handles detection, fingerprinting, extraction and a large body of evasion techniques. It is worth learning the manual methods first — boolean inference, time-based extraction, union alignment — because when a target needs a custom tamper script or sits behind a filter, the automation only helps if you understand what it's doing. Burp's scanner catches the straightforward cases during ordinary testing.

NoSQL. Tooling is thinner and testing is more manual. NoSQLMap exists but is far less mature. In practice the productive approach is to intercept a request, change a scalar field to an operator object, and watch the response: {"$ne": null}, {"$gt": ""}, {"$regex": "^a"}. The regex form is what turns a blind bypass into data extraction, one character at a time, by observing which prefixes match.

Both classes appear in the SQLi collection, and the blind-extraction techniques transfer between them more than the syntax suggests.

Defenses that actually transfer

Parameterization is the SQL answer and has no exact NoSQL equivalent, because there is no string being parsed. What does transfer is type discipline: validate that a field is the type you expect before it reaches the query layer, and reject anything else. A schema layer — Mongoose, a JSON Schema validator, a typed DTO — does this structurally rather than by remembering to check. Disable server-side evaluation features you don't use. And on both sides, run the database account with the minimum privileges the application needs, so that an injection that does succeed reaches less.

Common questions

Is NoSQL injection less serious than SQL injection?

No. It commonly produces authentication bypass and full data extraction, and on databases that evaluate server-side JavaScript it can reach code execution. What is true is that it's less standardized, which makes it harder to scan for and easier to miss.

Do parameterized queries prevent NoSQL injection?

The concept doesn't map directly, because there's no query string being parsed. The equivalent protection is type validation — ensuring a field that should be a string is a string before it reaches the driver — usually enforced by a schema layer rather than by hand.

Can NoSQL injection happen through a plain HTML form?

Yes, if the framework's body parser supports bracket notation. Express with qs, and PHP, will both turn user[$ne]= into a nested object, reconstructing exactly the payload people assume requires a JSON body.

Which databases are affected by NoSQL injection?

MongoDB gets the most attention because of its operator syntax, but the class covers any datastore where user input can alter query structure — including CouchDB, Redis command injection, and Elasticsearch query DSL manipulation.

How do I extract data from a blind NoSQL injection?

Regex operators. Submitting {"$regex": "^a"} and observing whether the response indicates a match lets you recover a value one character at a time — the same inference technique as boolean-based blind SQL injection, in different syntax.

More comparisons: SSRF vs CSRF XSS vs CSRF XSS Types AuthN vs AuthZ IDOR vs BOLA SAST vs DAST Bounty vs Pentest SBOM vs SLSA Validation vs Encoding DAST vs IAST vs RASP SCA vs SAST OAuth vs SAML Pentest vs Red Team WAF vs RASP