OWASP Web Top 10 — A03

NoSQL Injection

NoSQL Injection is a critical vulnerability that targets NoSQL databases like MongoDB, CouchDB, and Redis. Despite the "SQL" in the name, these databases are not immune to injection attacks. Attackers can manipulate queries to bypass authentication, extract sensitive data, or execute unauthorized operations.

What Is NoSQL Injection?

NoSQL Injection is a security vulnerability that exploits how NoSQL databases process user input. Unlike traditional SQL databases that use structured query language, NoSQL databases often use JSON-like query formats, key-value pairs, or graph structures. When applications fail to properly validate or sanitize user input before incorporating it into database queries, attackers can inject malicious operators, commands, or payloads that alter the intended behavior of the query.

The vulnerability is particularly dangerous in MongoDB deployments where JavaScript evaluation is enabled, allowing attackers to inject arbitrary JavaScript code that executes within the database context. Even without JavaScript execution, operator injection attacks can manipulate query logic using database operators like $ne (not equal), $gt (greater than), or $where to bypass authentication, access unauthorized data, or perform privilege escalation.

NoSQL Injection is classified under A03 (Injection) in the OWASP Top 10 2021. As NoSQL databases have grown in popularity for modern web applications, cloud services, and microservices architectures, the attack surface has expanded significantly. Many developers mistakenly believe that NoSQL databases are inherently immune to injection attacks, leading to inadequate input validation and widespread vulnerabilities in production systems.

How It Works

1
Application accepts user input

The application receives user input through login forms, search fields, API parameters, or JSON request bodies. This input is intended to be used in NoSQL queries to fetch or manipulate data. For example, a MongoDB-based authentication system might accept username and password fields.

2
Input is embedded into a NoSQL query

The application constructs a NoSQL query by directly embedding user input without proper validation or sanitization. For MongoDB, this might involve passing a JSON object containing user-supplied values directly to query methods like find() or findOne().

3
Attacker injects malicious operators

Instead of providing a simple string value, the attacker sends a JSON object containing NoSQL operators. For example, submitting {"$ne": null} as a password value instead of a string. This operator means "not equal to null," which will match any existing password value.

4
Query logic is altered

The injected operator changes the query's logical structure. A query intended to match {username: "admin", password: "userInput"} becomes {username: "admin", password: {"$ne": null}}, which matches any document where the username is "admin" and the password field is not null, effectively bypassing password verification.

5
Database executes the modified query

The NoSQL database processes the modified query without distinguishing between legitimate data and injected operators. It returns matching documents based on the altered logic, granting the attacker unauthorized access, exposing sensitive data, or allowing unauthorized operations.

Vulnerable Code Example

Vulnerable — Java / Spring Boot (MongoDB)
@RestController
public class AuthController {

    @Autowired
    private MongoTemplate mongoTemplate;

    @PostMapping("/login")
    public ResponseEntity<?> login(@RequestBody Map<String, Object> req) {

        // VULNERABLE: User input is directly passed to query
        // without validation or type checking
        Query query = new Query();
        query.addCriteria(
            Criteria.where("username").is(req.get("username"))
                .and("password").is(req.get("password"))
        );

        User user = mongoTemplate.findOne(query, User.class);

        if (user != null) {
            return ResponseEntity.ok(Map.of("user", user.getUsername()));
        }
        return ResponseEntity.status(401).body("Invalid credentials");
    }
}

// An attacker can bypass authentication by submitting:
// {
//   "username": "admin",
//   "password": { "$ne": null }
// }
//
// The query becomes:
// { username: "admin", password: { $ne: null } }
//
// This matches any user where password is not null,
// bypassing the password check entirely.

Secure Code Example

Secure — Java / Spring Boot (Sanitized Input)
@RestController
public class AuthController {

    @Autowired
    private MongoTemplate mongoTemplate;

    @PostMapping("/login")
    public ResponseEntity<?> login(@RequestBody LoginRequest req) {

        // SECURE: Use typed DTOs and validate input types
        // Ensure input is treated as strings, not operators
        String username = sanitizeInput(req.getUsername());
        String password = sanitizeInput(req.getPassword());

        Query query = new Query();
        query.addCriteria(
            Criteria.where("username").is(username)
                .and("password").is(password)
        );

        User user = mongoTemplate.findOne(query, User.class);

        if (user != null) {
            return ResponseEntity.ok(Map.of("user", user.getUsername()));
        }
        return ResponseEntity.status(401).body("Invalid credentials");
    }

    private String sanitizeInput(String input) {
        // Reject null and ensure it's a plain string
        if (input == null || input.trim().isEmpty()) {
            throw new IllegalArgumentException("Invalid input");
        }
        return input;
    }
}

// With type validation and sanitization:
// - Input is forced to be a String type
// - Object/operator payloads are rejected
// - Even if attacker sends {"$ne": null}, it's treated as
//   an invalid request rather than a query operator

Types of NoSQL Injection

Operator Injection

The most common NoSQL injection technique, particularly against MongoDB. Attackers inject query operators like $ne, $gt, $lt, $regex, or $where into query parameters. For example, using {"$ne": ""} in a password field creates a condition that matches any non-empty password. This technique bypasses authentication, enables data extraction, and can be used to enumerate database contents by crafting conditional queries that reveal information based on application responses.

JavaScript Injection

Exploits MongoDB's JavaScript execution capabilities through operators like $where, mapReduce, or $function. Attackers inject arbitrary JavaScript code that executes within the database context. For instance, $where: "this.password.match(/.*/) || true" can bypass authentication by always returning true. This technique can lead to server-side code execution, data exfiltration, or denial of service. While MongoDB 4.4+ disables JavaScript by default, many legacy deployments remain vulnerable.

Tautology-based Injection

Similar to SQL tautologies like 1=1, this technique creates conditions that are always true. In NoSQL contexts, attackers use operators like {"$gt": ""} (greater than empty string, matching all values) or {"$exists": true} (matches if field exists). These can be combined with logical operators like $or to create complex conditions that bypass validation. For example, {"$or": [{"admin": true}, {"admin": {"$exists": false}}]} matches either admin users or users without an admin field, potentially granting elevated privileges.

Impact

Successful NoSQL Injection attacks can compromise entire application security architectures, especially in cloud-native and microservices environments where NoSQL databases are prevalent. The consequences range from data breaches to complete system takeover.

Authentication and authorization bypass

Attackers can circumvent login mechanisms entirely by injecting operators that alter authentication logic. This grants immediate access to user accounts, administrative panels, or privileged API endpoints without valid credentials, enabling account takeover and unauthorized access to sensitive functionality.

Data exfiltration and privacy violations

Injection attacks enable extraction of sensitive documents, user profiles, financial records, and personal information. Attackers can enumerate entire collections, extract specific fields, or use regex operators to search for valuable data patterns like credit card numbers or API keys, leading to massive data breaches and regulatory violations.

Data corruption and integrity loss

Successful injection can enable unauthorized insert, update, or delete operations. Attackers can modify user permissions, alter transaction records, delete critical data, or inject malicious content into databases. In document stores, they can add new fields or nested objects that corrupt application logic or introduce backdoors.

Remote code execution and server compromise

JavaScript injection in MongoDB or command injection in Redis can escalate to arbitrary code execution on the database server. Attackers can read server files, execute system commands, establish reverse shells, or pivot to other systems within the infrastructure, potentially compromising entire cloud deployments or containerized environments.

Prevention Checklist

Use typed schemas and DTOs for input validation

Define strict data transfer objects (DTOs) or schemas that enforce expected data types. Ensure all user input is validated against these schemas before being used in queries. Reject any input that contains objects, arrays, or special operators. This prevents attackers from injecting structured payloads like {"$ne": null} by enforcing that password fields must be strings.

Sanitize input and strip operator characters

Implement input sanitization that removes or escapes MongoDB operators (characters starting with $) and special characters. Libraries like mongo-sanitize for Node.js or custom validation functions can strip out dangerous operators. Always validate that strings are actually strings and not nested objects or arrays.

Disable JavaScript execution in MongoDB

Set security.javascriptEnabled: false in MongoDB configuration to disable server-side JavaScript execution. This prevents $where, mapReduce, and $function injection attacks. MongoDB 4.4+ disables this by default, but older versions and custom configurations may still have it enabled. Regularly audit database configurations.

Apply principle of least privilege for database access

Configure database user accounts with minimal necessary permissions. Application database users should not have admin privileges, schema modification rights, or access to system collections. Use role-based access control (RBAC) to limit operations to only read and write on specific collections. This limits damage if injection occurs.

Use ORM/ODM libraries with built-in protection

Leverage Object-Document Mappers like Mongoose (Node.js), Morphia (Java), or MongoEngine (Python) that provide schema validation and input sanitization. Configure strict mode to reject undefined schema fields. While not foolproof, these libraries significantly reduce the attack surface when properly configured and used consistently.

Implement security testing and monitoring

Integrate NoSQL injection testing into CI/CD pipelines using tools like NoSQLMap or custom security test suites. Monitor database query logs for suspicious patterns like excessive operator usage or unusual query structures. Deploy Web Application Firewalls (WAFs) with NoSQL injection detection rules. Conduct regular penetration testing focused on NoSQL vulnerabilities.

Real-World Examples

2016

27,000 MongoDB Databases Ransomed

In early 2016, over 27,000 publicly accessible MongoDB databases were compromised by attackers exploiting default configurations and injection vulnerabilities. Attackers deleted data and left ransom notes demanding Bitcoin payments. Many instances lacked authentication entirely, while others were vulnerable to injection attacks that bypassed weak security controls, exposing the widespread misconfiguration of NoSQL deployments.

2020

Alibaba Cloud MongoDB Breach

Security researchers discovered that multiple applications running on Alibaba Cloud were vulnerable to NoSQL injection attacks via MongoDB. The vulnerabilities allowed authentication bypass and unauthorized access to customer data including personal information, order histories, and payment details. The incident highlighted how cloud-native applications often underestimate NoSQL security requirements.

2021

Hotel Booking Platform Data Leak

A major hotel booking platform suffered a data breach when attackers exploited NoSQL injection vulnerabilities in their MongoDB-based reservation system. Using operator injection techniques, attackers extracted over 10 million customer records including names, email addresses, phone numbers, and booking histories. The breach resulted from inadequate input validation in API endpoints that directly passed JSON request bodies to database queries.

2022

E-commerce Platform Admin Access

Security researchers demonstrated critical NoSQL injection vulnerabilities in several popular e-commerce platforms built on Node.js and MongoDB. By injecting {"$ne": null} operators into login forms, they achieved complete administrative access without credentials. The vulnerability affected checkout systems, inventory management, and customer databases, highlighting the critical need for input validation in modern web applications.

Ready to Test Your Knowledge?

Put what you have learned into practice. Try identifying and fixing NoSQL Injection vulnerabilities in our interactive coding challenges, or explore more security guides to deepen your understanding.