How the attack works
At the core of every injection is the missing separation of code and data. An application builds dynamic queries or commands via string concatenation with user input.
The interpreter (SQL database, NoSQL engine, shell) can then no longer distinguish what was originally the intended command from what was injected input.
- SQL: a WHERE clause is built via concatenation, and the attacker smuggles in additional SQL logic using characters like ', --, or OR 1=1.
- NoSQL/MongoDB: instead of a string, the attacker sends a nested object with query operators in a JSON body, such as {"$ne":"invalid"} or {"$in":[...]}, that bend the query logic; some engines even allow JavaScript execution via $where.
- OS command: user input ends up in a command passed to the shell; metacharacters like &, |, ;, or ` chain additional commands (PortSwigger names & && | || as cross-system command separators).
According to OWASP, the rule holds throughout: only a parameterized/safe API reliably separates code and data. Prepared statements bind all SQL parts in advance and treat inputs purely as values.
Unvalidated input ends up mixed into queries or commands, undivided.
Example
NoSQL operator injection for authentication bypass via a JSON login (PortSwigger).
- Expected request to a login API:
POSTwithContent-Type: application/jsonand body{"username":"wiener","password":"peter"}. The app builds a MongoDB query from this that compares username and password. - Attack - the client replaces the string values with nested operator objects:
{"username":{"$ne":"invalid"},"password":{"$ne":"invalid"}}. - Effect, according to PortSwigger: if both inputs are processed as operators, the query returns all records where the username and password are not equal to "invalid" - the attacker is logged in as the first user in the collection, without a valid password.
- Targeting a known/guessed account, PortSwigger notes, a payload can be built like:
{"username":{"$in":["admin","administrator","superadmin"]},"password":{"$ne":""}}.
Source: PortSwigger.
Impact
Unauthorized access to sensitive data (passwords, credit card data, personal data), alteration or deletion of data, as well as bypassing authentication and access controls.
According to PortSwigger, SQL injection has been the cause of many high-profile data breaches with reputational damage and regulatory penalties, in some cases with persistent backdoor access.
According to PortSwigger, NoSQL injection can additionally bypass authentication, extract/modify data, cause denial of service, and execute code on the server.
OS command injection typically leads to complete compromise of the application and its data, and allows pivoting to other systems in the infrastructure.
How to protect yourself
- Use safe/parameterized APIs (OWASP's primary defense): for SQL, prepared statements with variable binding or parameterized queries; analogously ORM/HQL named parameters - this way the database separates code and data independently of the input.
- Avoid calling OS commands directly wherever possible - use library functions instead (e.g. mkdir() instead of system("mkdir ...")); if the call can't be avoided, combine parameterization (e.g. Java's ProcessBuilder with separate arguments, no shell invocation) with input validation.
- Use positive/allowlist input validation as an additional layer (not as the sole defense): check commands against an allowed list, validate arguments with a strict allowlist regex including a length limit and without metacharacters (& | ; $ > < ` \ ! ' " ( )) and without whitespace.
- For NoSQL/JSON APIs, enforce expected data types: validate values as strings and reject nested operator objects, so that no $ne/$in/$where operators reach the query.
- If no parameterized API is available, escape inputs context-specifically using the correct escape syntax of the respective interpreter (listed by OWASP only as a last resort, and explicitly rated STRONGLY DISCOURAGED for SQL).
- Implement least privilege: keep database and process permissions minimal, with isolated accounts with limited rights per task, to limit the damage in case of exploitation.
Sources
- Injection Prevention Cheat Sheet OWASP Cheat Sheet Series, 2024
- SQL Injection Prevention Cheat Sheet OWASP Cheat Sheet Series, 2024
- OS Command Injection Defense Cheat Sheet OWASP Cheat Sheet Series, 2024
- What is SQL injection (SQLi)? Tutorial & Examples PortSwigger Web Security Academy, 2024
- NoSQL injection PortSwigger Web Security Academy, 2024
- What is OS command injection, and how to prevent it? PortSwigger Web Security Academy, 2024