Video Demonstration: Mass Assignment Attack in MongoDB Application

Blogging platform

Watch a real-time demonstration of how mass assignment vulnerabilities work in a Node.js and MongoDB application. This video shows an attacker manipulating the balance field during user registration - a critical vulnerability that can lead to financial fraud and privilege escalation.

⚠️ Important: This demonstration is for educational purposes only. Never attempt these attacks on systems you don't own or have explicit permission to test.


📹 Video Demonstration

Complete walkthrough of mass assignment exploitation in a Node.js application

🎯 What This Video Demonstrates

This hands-on video demonstration walks you through:

1. MongoDB Schema Setup

See the vulnerable User schema in MongoDB with mongoose that includes username, password, and balance fields with default values.

2. Balance Manipulation Attack

Watch in real-time as an attacker injects a balance: 500 field during signup to give themselves free money instead of the default balance of 0.

3. Using Postman for Testing

Learn how to use Postman to test API endpoints and demonstrate how attackers can exploit mass assignment vulnerabilities in REST APIs.


📚 Understanding the Demonstration

The Vulnerable Application Setup

The demonstration uses a Node.js application with the following stack:

  • Backend: Node.js with Express.js
  • Database: MongoDB with Mongoose ODM
  • Authentication: bcrypt for password hashing
  • API Testing: Postman for sending requests

The Vulnerable Code

The video shows the actual code from the demonstration. Here's what makes it vulnerable:

1. User Schema (User.js):

const mongoose = require('mongoose');
const bcrypt = require('bcrypt');

const UserSchema = new mongoose.Schema({
  username: { type: String, unique: true },
  password: { type: String, required: true },
  balance: { type: Number, required: true, default: 0 }
});

The schema defines a balance field with a default value of 0. This should only be set by the server, never by user input.

2. Vulnerable SignUp Route (signUp.js):

// ❌ VULNERABLE CODE
const signup = function (req, res) {
  // --- attempt to sign up user ---
  db.createNewUser(req.body, (user, error) => {
    if (error) {
      console.log(error)
    }
    else {
      console.log(user)
    }
  })
}

🚨 The Problem: The code passes req.body directly to createNewUser(), which means ALL fields from the request are accepted, including fields that should never come from user input like balance!


💥 The Attack Demonstration

Step 1: Normal User Signup

First, the video shows a legitimate user registration with only the required fields:

POST http://localhost:3000/auth/sign-up
Content-Type: application/json

{
  "username": "test",
  "password": "test"
}

Expected Result: User created with balance: 0 (the default value)

// Terminal Output:
{ username: 'test', password: 'test', balance: 0 }

Step 2: The Attack - Injecting Balance Field

Next, the video demonstrates the mass assignment attack by adding a balance field to the request:

POST http://localhost:3000/auth/sign-up
Content-Type: application/json

{
  "username": "test",
  "password": "test",
  "balance": 500        // 🚨 INJECTED FIELD
}

Attack Result: User created with balance: 500 instead of 0!

// Terminal Output (VULNERABLE):
{ username: 'test', password: 'test', balance: 500 }
// 😱 The attacker gave themselves $500 for free!

💥 Critical Impact: An attacker can now sign up with any balance they want! This could lead to:

  • Financial fraud - Free money in their account
  • System abuse - Unlimited credits or resources
  • Business loss - Company loses money on fraudulent accounts

Step 3: Restarting Server & Verifying Persistence

The video shows restarting the Node.js server and testing again to demonstrate this isn't a one-time glitch - it's a persistent vulnerability in the code.

// Terminal shows server restart:
PS C:\Users\DevBox\Desktop\demo-app\server> ^C
PS C:\Users\DevBox\Desktop\demo-app\server> ^C
PS C:\Users\DevBox\Desktop\demo-app\server> node .\index.js
Example app listening on port 3000
---> connected to database

After restart, the same attack still works - confirming it's a code vulnerability, not a temporary bug.


🛡️ The Secure Solution

The video explains how to fix this vulnerability. Here are the proper implementations:

Solution 1: Explicit Field Extraction (Recommended)

// ✅ SECURE CODE
const signup = function (req, res) {
  // Only extract the fields we want to accept
  const userData = {
    username: req.body.username,
    password: req.body.password
    // balance is NOT included - will use schema default of 0
  };

  db.createNewUser(userData, (user, error) => {
    if (error) {
      console.log(error)
    }
    else {
      console.log(user)
    }
  })
}

Solution 2: Object Destructuring with Whitelisting

// ✅ SECURE CODE (Alternative)
const signup = function (req, res) {
  // Destructure only the allowed fields
  const { username, password } = req.body;

  db.createNewUser({ username, password }, (user, error) => {
    if (error) {
      console.log(error)
    }
    else {
      console.log(user)
    }
  })
}

Solution 3: Input Validation Middleware

// ✅ SECURE CODE (Using express-validator)
const { body, validationResult } = require('express-validator');

app.post('/auth/sign-up',
  // Validation middleware
  body('username').isString().notEmpty(),
  body('password').isString().isLength({ min: 6 }),
  // Only these fields are validated - others are rejected

  (req, res) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      return res.status(400).json({ errors: errors.array() });
    }

    const { username, password } = req.body;
    db.createNewUser({ username, password }, (user, error) => {
      // ...
    })
  }
);

✅ Result: With these fixes, even if an attacker sends balance: 500, it will be ignored. The user will be created with the schema's default balance: 0.


🔍 Real-World Financial Impact

The balance manipulation shown in the video demonstrates a critical vulnerability with serious consequences:

Scenario Impact Financial Loss
E-commerce store credits Attacker creates account with $1000 balance Direct loss per attack
Gaming platform currency Unlimited in-game currency on signup Lost revenue from virtual goods
SaaS platform credits Free API calls or service usage Infrastructure costs + lost subscriptions
Banking/Fintech app Account created with fake balance Regulatory fines + reputation damage

🛠️ Tools Used in the Demonstration

1. Visual Studio Code

The video shows VS Code as the development environment, displaying:

  • User.js - MongoDB schema with mongoose
  • signUp.js - Vulnerable signup route
  • Terminal - Server logs showing created users

2. Postman

Postman is used to send HTTP requests to the API, demonstrating:

  • POST requests to http://localhost:3000/auth/sign-up
  • JSON body with username and password (normal)
  • JSON body with injected balance field (attack)
  • Viewing responses and errors

3. Node.js Server

The backend server running on port 3000 with:

  • Express.js for routing
  • MongoDB connection for data persistence
  • bcrypt for password hashing
  • Console logging to show user creation

💡 Key Takeaways from the Video

  1. Never pass req.body directly to database operations: Always explicitly define which fields to accept
  2. MongoDB schemas with defaults aren't enough: Even with default: 0, user input can override it
  3. Balance and monetary fields are high-value targets: Attackers will always try to manipulate financial data
  4. Use destructuring or explicit extraction: Only take the fields you need from the request
  5. Test your APIs with Postman: Add extra fields to requests to verify they're rejected
  6. Validate input at multiple layers: Use express-validator or similar tools for comprehensive validation

🧪 How to Reproduce This Demonstration

Want to test this yourself? Here's how to set up a similar test environment:

Step 1: Create the Vulnerable App

# Initialize Node.js project
npm init -y

# Install dependencies
npm install express mongoose bcrypt

# Create server files
# - index.js (main server file)
# - User.js (mongoose schema)
# - signUp.js (auth route)

Step 2: Set Up MongoDB

# Option 1: Local MongoDB
# Install from mongodb.com

# Option 2: MongoDB Atlas (free cloud)
# Sign up at mongodb.com/cloud/atlas
# Get connection string

# Add to your code:
mongoose.connect('mongodb://localhost:27017/demo-app');

Step 3: Test with Postman

In Postman:

  1. Create a new POST request
  2. Set URL to http://localhost:3000/auth/sign-up
  3. Set Headers: Content-Type: application/json
  4. Set Body (raw JSON):
{
  "username": "testuser",
  "password": "password123",
  "balance": 9999999
}

If the server accepts the balance field, it's vulnerable!


📊 Related Vulnerabilities

Mass assignment can be exploited to manipulate various sensitive fields:

Privilege Escalation

{
  "username": "hacker",
  "isAdmin": true,
  "role": "admin"
}

Gain administrator access

Account Takeover

{
  "username": "victim",
  "userId": "other_user_id",
  "ownerId": 12345
}

Modify ownership or user ID

Financial Fraud

{
  "username": "thief",
  "balance": 1000000,
  "credits": 999999
}

Manipulate monetary values

Status Manipulation

{
  "username": "faker",
  "verified": true,
  "approved": true
}

Bypass verification processes


✅ Security Best Practices

Based on the video demonstration, implement these security measures:

Input Whitelisting Checklist:

  • ☑️ Extract only expected fields from req.body using destructuring
  • ☑️ Never pass req.body directly to database operations or constructors
  • ☑️ Set sensitive fields server-side (balance, isAdmin, role, etc.)
  • ☑️ Use validation libraries like express-validator or joi
  • ☑️ Implement Data Transfer Objects (DTOs) to define allowed fields
  • ☑️ Test APIs with extra fields to ensure they're ignored
  • ☑️ Review all POST/PUT/PATCH endpoints for mass assignment risks
  • ☑️ Enable strict schema validation in MongoDB/Mongoose
  • ☑️ Log suspicious requests with unexpected fields
  • ☑️ Conduct security code reviews before deployment

🎓 Learning Resources

To learn more about mass assignment and API security: