Skip to main content

Command Palette

Search for a command to run...

Hunting Vulnerabilities and Securing MizbanApp: Mass Assignment & IDOR

Updated
6 min read
Hunting Vulnerabilities and Securing MizbanApp: Mass Assignment & IDOR

Intro,

Yo, I hope you’re all doing well!
I decided to write a new article once again. The journey of finding these vulnerabilities started when I came across a post about MizbanApp on LinkedIn — an application where you can discover restaurants, cafés, and more. It’s built by Afghan developers for Afghan people, so kudos to them for pushing Afghanistan further into the digital age.

First Vulnerability: Becoming Admin

As the title implies, I was able to gain admin access in the application compromising entire application. The vulnerability that made this possible is known as Mass Assignment. In this section, I’ll briefly explain what Mass Assignment is and then walk you through the process of discovering and exploiting it.

What is Mass Assignment?

Mass Assignment is a vulnerability that occurs when an application automatically assigns user-supplied input to internal objects or database fields without proper filtering or restrictions. This can allow an attacker to modify fields they shouldn’t have access to. for example, changing their own role to admin.

Discovery & Exploitation: Mass Assignment on MizbanApp

I started by creating an account and logging in. I quickly noticed that the application was still under development, and some features weren’t fully implemented yet. I began mapping the app and navigated to my profile, which simply displayed my information. However, when I intercepted the request, I observed an API call to:

GET /api/v1/user/profile HTTP/1.1
Host: site.com

As you can see from the request and response, this API endpoint loads your profile information. It returns all the details the application knows about you:

At this point, I thought to myself — if there’s a route to show my profile info, there should probably be a function (HTTP method) or route to update it as well. Classic hacker thinking :))

So, I tried changing the HTTP method to POST, PUT, and PATCH, and noticed something interesting. The PATCH request returned a different JSON response. To my surprise, it even leaked my hashed password and included a field called role: customer. Wow — that was a clear sign that something interesting was happening.

As you can probably guess, I added "role": "admin" to the request body to see if I could actually change my role. And guess what? Yes! Surprisingly, it worked — I was able to change my role to admin 😎🎉

After that, I wanted to prove that this actually worked. To confirm, I logged out and then logged back in to my account. As shown in the image below, I was now an admin, and the admin dashboard appeared.

From there, I had full control — I could add, edit, or delete restaurants, manage users, see their feedback, and basically do anything an admin can do. This clearly demonstrated the severity of the Mass Assignment vulnerability.

Root Cause of Mass Assignment

The root cause of this Mass Assignment vulnerability is insufficient input filtering and improper handling of user-supplied data. Essentially, the application blindly accepted fields from the request body and mapped them directly to database attributes — including sensitive fields like role.

For example, in a Node.js/Express app using Mongoose, an insecure implementation might look like this:

// Insecure code
app.patch('/api/v1/user/profile', async (req, res) => {
  const user = await User.findById(req.user.id);
  Object.assign(user, req.body); // blindly assigns all user input
  await user.save();
  res.json(user);
});

Here, any field sent in the request body, including role, will be updated in the database.

A safer approach would be to whitelist only allowed fields:

// Secure code
app.patch('/api/v1/user/profile', async (req, res) => {
  const user = await User.findById(req.user.id);
  const allowedFields = ['name', 'email']; // whitelist only safe fields
  allowedFields.forEach(field => {
    if (req.body[field] !== undefined) {
      user[field] = req.body[field];
    }
  });
  await user.save();
  res.json(user);
});

This ensures that sensitive fields like role cannot be modified by the user, preventing Mass Assignment exploits.

Second Vulnerability: IDOR Leading to Viewing Users’ Information

After discovering the first vulnerability, I shared it with my friend. He was curious and asked me how to reproduce the Mass Assignment (we’re both learning). During our chat, he mentioned that there might be an IDOR vulnerability in the app as well!

Before diving in, let’s first understand what IDOR is.

What is IDOR?

IDOR (Insecure Direct Object Reference) is a vulnerability that occurs when an application allows users to access objects or data they shouldn’t just by changing a parameter, like an ID in a URL or request. In simple terms, it’s like giving someone a key to a locker they don’t own — the app fails to check if they’re allowed to access it.

Discovery & Exploitation: IDOR on MizbanApp

My friend, Nadir, mentioned that the application is vulnerable to IDOR and that you could retrieve users’ information using their UUIDs via this API endpoint:

GET /api/v1/user/UUID HTTP/1.1
Host: site.com

In addition to the usual /api/v1/user/profile API endpoint. He thought it might not be exploitable because guessing users’ UUIDs would be extremely difficult — they’re long and random.

But here’s what I thought :), I had mapped the app and realized that users can post reviews on restaurants. By intercepting the responses, I noticed that users’ UUIDs were actually being leaked along with their reviews. This made the IDOR vulnerability exploitable after all!

So, I asked Nadir to post a review on a restaurant. As you can see in the intercepted response, his _ID was leaked along with his name and review.

By replacing this ID with our own UUID in the API request, I was able to retrieve Nadir’s full object data, which included his name, email, role, favorite restaurants, and all his reviews.

Fields like email, role, isVerified, favorite restaurants, and favorite dishes are sensitive and should never be exposed. Yet, in this case, we could access all of this information simply by changing or obtaining a user’s UUID. This clearly demonstrates the severity of the IDOR vulnerability in MizbanApp.

Root Cause of IDOR

The main reason IDOR occurs is improper access control. The application assumes that if someone knows an object’s ID (like a UUID), they’re allowed to access it, without actually verifying whether the user has permission. In other words, the server doesn’t check ownership or roles before returning sensitive data.

How to Secure Against IDOR

Verify Ownership / Access Rights
Always check that the authenticated user has permission to access the requested object. For example:

app.get('/api/v1/user/:uuid', async (req, res) => {
  const user = await User.findOne({ uuid: req.params.uuid });

  // Ensure the logged-in user is requesting their own data
  if (user.id !== req.user.id) {
    return res.status(403).json({ error: 'Access denied' });
  }

  res.json(user);
});

Final Words

I hope this article gave you some insight into how Mass Assignment and IDOR vulnerabilities work in real-world applications. All of these issues were responsibly reported to the MizbanApp team, who responded professionally and promptly patched the vulnerabilities.

Security is a shared responsibility — even small mistakes can have big consequences, but with awareness and proper practices, we can make applications safer.
Be happy,
Be nice,

References

OWASP cheatsheet for Mass Assignment

What is Mass Assignment

OWASP IDOR