From App User to Tenant Admin
Tags: opensource, hacking, bugbounty, api
Published: 2022-09-19 08:59:14

Hello there, y'all! Hope you are doing great 🤗

Today, I'm gonna be sharing with you the process of finding [CVE-2022-3225](https://huntr.dev/bounties/a13a56b7-04da-4560-b8ec-0d637d12a245/). Just like the last post, what I am about to show is not complex at all, but it's really cool and similar bugs can still be found out there!


## 🏞️ Continuing The Journey of Securing Low Code App Builders

Right after finding the last bug on Tooljet, I decided to look for issues in similar projects, so I googled for `Tooljet vs ` and found some software with very near concepts and goals. One of those was Budibase, and I arbitrarily pick it as a new application for testing.

One thing I like to do is to map what parts of the code can directly interact with user input. I do that just by using the app and monitoring requests with Burp or ZAP. So I got that the "immediate" logic was being handled by controllers, and then I took a look at most of them, hoping for spotting something strange happening.


![Detective Pikachu](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pkiv4db0w94opgtoaeyz.gif)


## 😱 Look! A Mass Assignment!

Out of all those different methods, one that got my attention was the method which updates your own user's information. Why? Well, because it clearly was doing a mass assignment!

If you don't know what it means, I explain it a little bit better [here](https://dev.to/therealbrenu/api62019-mass-assignment-3b76). But this pseudocode **resumes** what the function was looking like:

```php
function updateSelf(request) {
  self := User::findOrFail(request.params.id)
  # ...some other logic here...
  self.update(request.body)

  return self
}
```

It was picking up the entire request body and using it to update our user data 😱. This means that if we inserted valid user attributes that are not in the original request made by the browser, it would still work! So I looked for my user's object in some HTTP requests, including this specific one, and noticed some interesting attributes:

```javascript
{
...
    "builder": {
        "global":true
    },
    "admin": {
        "global":true
    },
...
}
```

So I decided to set this `admin.global` value to false, and...Boom! I was not an admin of my tenant anymore, yaaaaay! No, wait! It's not something good 😭

Luckily, when trying to set it back to true, it also worked 😅

## 🫠 Bringing Some Impact

Okay, but what can we do with it?

![try to take over the world ](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4ng5k69sdd5zfzrur7og.gif)

As an administrator, it doesn't bring any harm to be able to change my own access levels, but this endpoint is available to any authenticated user. So I looked for the lowest access level that exists, and this is the `App User`. It's a user that has basically no permissions, other than being capable of running specific apps from the given tenant.

The app user also has access to a form where they can change their "display name", and this form calls the vulnerable endpoint. So I tried to change the role of my app user to admin and...it worked! 🥳

Again, okay...but what can we do with it? 🧐

After digging a little bit, I found that as an admin, I could delete all of the other accounts (including the account of the original admins), and also delete every app or change their content to something else.

In other words: with one single request, any simple app user could become capable of ruining an entire tenant.

So I reported it to Budibase, and after validating the bug, they fixed it really fast! Kudos to Budibase mantainers for being amazing! 🤩

## Thank you for taking your time 🤗