Thursday, December 4, 2025

thumbnail

Avoiding Injection Attacks in MongoDB

 Avoiding injection attacks in MongoDB is crucial for protecting MERN and Node.js applications. MongoDB is vulnerable to a specific family of attacks called NoSQL injection, where attackers manipulate query objects to access or modify data they shouldn’t.


Below is a clear, comprehensive, best-practice guide on how to prevent MongoDB injection attacks.


Avoiding Injection Attacks in MongoDB


Injection attacks occur when untrusted input is passed directly into a MongoDB query.

For example:


// ❌ Dangerous

User.findOne({ username: req.body.username });



If req.body.username contains something like:


{ "$gt": "" }



the query becomes:


{ username: { $gt: "" } }



→ This returns the first user in the database — a serious security flaw.


MongoDB injection is different from SQL injection, but just as dangerous.


1. Always Validate and Sanitize Inputs


Use a schema validation library:


✔ Joi

✔ Zod

✔ Yup

✔ express-validator


Example with Joi:


const schema = Joi.object({

  username: Joi.string().alphanum().min(3).max(30).required(),

});


await schema.validateAsync(req.body);



This ensures unsafe objects (like $gt, $regex) don't get through.


2. Use Mongoose Strict Mode (Recommended)


Mongoose prevents unexpected fields by default (strict: true).

Make sure it stays on:


const UserSchema = new mongoose.Schema(

  { username: String, password: String },

  { strict: true }

);



Also avoid allowing arbitrary nested objects unless validated.


3. Never Pass Raw Input Directly into Queries


Instead of:


User.findOne({ username: req.body.username })



do:


const username = String(req.body.username);

User.findOne({ username });



Casting to string prevents injection.


4. Block MongoDB Operators in User Input


Hackers commonly inject:


$gt, $ne, $or, $eq, $regex, $where



To reject operator-based queries:


Option A — Use express-mongo-sanitize


(Highly recommended)


npm install express-mongo-sanitize


const mongoSanitize = require('express-mongo-sanitize');

app.use(mongoSanitize());



This removes keys like $ or . from incoming JSON.


Option B — Manually filter operators

function sanitize(obj) {

  for (const key in obj) {

    if (key.startsWith("$")) delete obj[key];

    if (typeof obj[key] === "object") sanitize(obj[key]);

  }

}

sanitize(req.body);


5. Avoid Using $where or Dynamic Queries


Never use user input inside:


$where


$regex


Aggregation expressions


Dynamic field names


Example of dangerous code:


// ❌ Vulnerable – user-provided JS!

User.find({ $where: req.body.jsCode });



Never allow users to inject JavaScript.


6. Use Parameterized Operators Safely


If you need to allow searching with regex:


const sanitized = escapeRegex(req.query.search);

User.find({ name: new RegExp(sanitized, "i") });



Helper:


function escapeRegex(str) {

  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");

}


7. Limit Query Scope and Data Return

Use projections:

User.find({}, "username email")


Use rate limiting:


Protects against brute-force injection attempts.


Use access control:


Don’t expose admin-level queries to users.


8. Enforce Schema Validation at the Database Level


MongoDB supports built-in schema validation:


db.createCollection("users", {

  validator: {

    $jsonSchema: {

      bsonType: "object",

      required: ["username", "email"],

      properties: {

        username: { bsonType: "string" },

        email: { bsonType: "string" }

      }

    }

  }

});



Even if an attacker bypasses your app, the database rejects invalid data.


9. Use Least-Privilege MongoDB Accounts


Never connect as admin.


Use a database user with read/write on only one database:


db.createUser({

  user: "app",

  pwd: "secure-password",

  roles: [{ role: "readWrite", db: "appdb" }]

});



Prevents catastrophic damage if injection occurs.


10. Turn Off eval and Disallow JavaScript Execution


Disable server-side JavaScript:


--noscripting



Or in MongoDB config:


security:

  javascriptEnabled: false



This blocks $where from executing attacker-provided code.


11. Use Web Application Firewalls (Optional)


Cloudflare WAF, AWS WAF, or GCP Cloud Armor can block requests containing MongoDB operators like:


$ne, $regex, $where, $gt, $or



This adds an extra layer of defense.


Summary (Cheat Sheet)

✔ Validate all inputs

✔ Use Mongoose strict mode

✔ Sanitize MongoDB operators ($, .)

✔ Avoid raw queries from user input

✔ Block $where, dynamic regex, and injected operators

✔ Implement database-level schema validation

✔ Use least-privilege database credentials

✔ Disable server-side JS execution


With these practices, your MongoDB-backed MERN application becomes highly resistant to injection attacks.

Learn MERN Stack Training in Hyderabad

Read More

HTTPS in MERN Applications

Secure File Uploads in MERN

Rate Limiting & Throttling with Express

Using Helmet for Express Security

Visit Our Quality Thought Training Institute in Hyderabad

Get Directions 

Subscribe by Email

Follow Updates Articles from This Blog via Email

No Comments

About

Search This Blog

Powered by Blogger.

Blog Archive