| name | sc-nosqli |
| description | NoSQL Injection detection for MongoDB, Redis, CouchDB, and Elasticsearch |
| license | MIT |
| metadata | {"author":"ersinkoc","category":"security","version":"1.0.0"} |
SC: NoSQL Injection
Purpose
Detects NoSQL injection vulnerabilities where user-controlled input manipulates NoSQL database queries. Unlike SQL injection, NoSQL injection exploits operator injection, JSON structure manipulation, and JavaScript execution within query contexts. Covers MongoDB, Redis, CouchDB, DynamoDB, and Elasticsearch.
Activation
Called by sc-orchestrator during Phase 2. Runs when NoSQL databases are detected in the architecture.
Phase 1: Discovery
File Patterns to Search
**/*.ts, **/*.js, **/*.py, **/*.php, **/*.java, **/*.go, **/*.cs,
**/models/*, **/controllers/*, **/services/*, **/repositories/*,
**/*mongo*, **/*redis*, **/*elastic*, **/*couch*, **/*dynamo*
Keyword Patterns to Search
# MongoDB
"find(", "findOne(", "findOneAndUpdate(", "findOneAndDelete(",
"aggregate(", "updateOne(", "updateMany(", "deleteOne(", "deleteMany(",
"$where", "$regex", "$gt", "$gte", "$lt", "$lte", "$ne", "$in", "$nin",
"$or", "$and", "$not", "$exists", "$expr",
"MongoClient", "mongoose.model", "collection.find"
# Redis
"redis.get(", "redis.set(", "redis.eval(", "redis.send_command(",
"EVAL ", "EVALSHA", "redis.call("
# Elasticsearch
"client.search(", "client.index(", "query_string",
"script_score", "painless", "elasticsearch"
# CouchDB
"_find", "mango", "cloudant"
Data Flow Tracing
Sources: HTTP request body (JSON), query parameters, headers, cookies
Sinks:
- MongoDB:
collection.find(), collection.findOne(), Model.find(), aggregate() — when query object is constructed from user input
- Redis:
EVAL with user input in script, redis.send_command() with dynamic commands
- Elasticsearch:
query_string query with user input, script fields with user input
Phase 2: Verification
Exploitability Checklist
- Can the attacker inject MongoDB operators (
$gt, $ne, $regex, $where) into the query?
- Can the attacker modify the query structure by injecting JSON keys?
- Can the attacker inject JavaScript code into
$where or $function expressions?
- Is the request body parsed as JSON and passed directly to the database driver?
Sanitization Check
- Is input validated against expected types (string, number, ObjectId)?
- Are MongoDB operators stripped from user input?
- Is input sanitized using a library like
mongo-sanitize or express-mongo-sanitize?
- Is Mongoose schema validation enforced before query execution?
Framework Protection Check
- Mongoose with schema: Schema validation prevents type confusion but NOT operator injection in
.find() with raw objects
- Prisma (MongoDB): Prisma abstracts queries and prevents operator injection
- Spring Data MongoDB:
MongoTemplate with Criteria API is safe; raw query strings are not
MongoDB Operator Injection Example
app.post('/login', async (req, res) => {
const user = await User.findOne({
username: req.body.username,
password: req.body.password
});
});
app.post('/login', async (req, res) => {
if (typeof req.body.username !== 'string' || typeof req.body.password !== 'string') {
return res.status(400).json({ error: 'Invalid input' });
}
const user = await User.findOne({
username: req.body.username,
password: req.body.password
});
});
MongoDB $where Injection
const results = await collection.find({
$where: `this.category == '${req.query.category}'`
});
const results = await collection.find({
category: req.query.category
});
Redis EVAL Injection
script = f"return redis.call('get', '{user_input}')"
result = redis_client.eval(script, 0)
result = redis_client.get(user_input)
Elasticsearch Query String Injection
const results = await client.search({
query: {
query_string: {
query: req.query.search
}
}
});
const results = await client.search({
query: {
match: {
content: req.query.search
}
}
});
Severity Classification
- Critical: Authentication bypass via operator injection, or JavaScript execution via
$where/$function with user input
- High: Data exfiltration through query manipulation, unauthorized access to other users' data
- Medium: Query manipulation with limited impact (e.g., bypassing filter conditions)
- Low: Information disclosure through error messages revealing database structure
Output Format
Finding: NOSQLI-{NNN}
Common False Positives
- Prisma/Mongoose with strict schema — typed models prevent operator injection when schema validation is enforced
- Hardcoded queries — query objects built entirely from constants, not user input
- Internal service-to-service calls — query parameters come from trusted internal services, not HTTP requests
- Admin/seed scripts — database operations in setup scripts that don't handle user input
- Aggregation pipelines with static structure — pipeline stages defined in code with only values from user input (parameterized)