Akwaaba! seniors. I will quickly tell you about a recent bounty of $1,500 I received from a program. Before I get into it, POST-based XSS can still be exploited to earn bounties. $2000 Android Content Provider bug and this has nothing to do with Burp Suite.

‼️ Disclaimer: I've changed specific details about the application in this write-up for confidentiality. Even the screenshots shown are from a different, similar application that doesn't have a bug bounty program — they're only used for illustration. Also, all API endpoints mentioned have been altered to avoid revealing the actual program.

The Program

I recently received a private invite to a program that included two main assets: app.target.com and api.target.com. The program provided a single set of credentials for logging into the application, signups were disabled.

From my initial checks, the platform appeared to be focused on document and secrets management. One interesting feature was the ability to create teams and add other users to those teams. While I could see the names of teams created by other users, no additional details such as members or permissions were visible to me.

The Vulnerability

After some deep recon, I uncovered hidden functionality that exposed sensitive information about other users' teams. This included member names, roles, email addresses, UUIDs, special notes, and even private keys.

While exploring the app, I noticed a feature that lets you create a secret item and share it with individual users or entire teams. During this process, the app reveals team names and their UUIDs, even for teams you don't belong to — which is expected behavior. Behind the scenes, an API call is made to the following endpoint to fetch team names only:

GET /api/v1/<workspace-UUID>/teams
Host: api.target.com
Authorization: Bearer ey...

Of course, following REST framework's standards, we can attempt to retrieve info about specific teams by appending their UUID or attaching it as a parameter. In this case, appending it in the path worked.

''====Request====''
GET /api/v1/<workspace-UUID>/teams/<team-UUID>
Host: api.target.com
Authorization: Bearer ey...


''====Response====''
HTTP 200 OK
Server: Apache

{
  "status": "success",
  "data": {
    "teams": [
      {
        "name": "First Team",
        "uuid": "a3f9c2e4-7b8d-4d1a-9f2e-1c3b5a6d8e9f"
      },
      {
        "name": "Another User's Team"
        "uuid": "b7d4e8f1-2c3a-4e9b-8d7f-5a6c9b3e2f1d"
      },
      {
        "name": "Internal Team",
        "uuid": "c9e1f3a7-6d8b-4f2c-9a1e-3b5d7e8f2c4a"
      }
    ]
  }
}

After trying to fuzz beyond the team UUID to uncover additional endpoints, none of my wordlists returned anything useful. Since signups were disabled on the main app, I shifted focus to see if UAT, Staging, Test, or Demo environments existed. These often have signup enabled and can provide extra attack surface.

I'm sneaking in this article to show you why hacking an IoT Android app to control home appliances via a Broadcast Receiver is easier than you might think.

Reconnaissance to Identify Related Assets

I don't like fuzzing subdomains; I suck at it. So, I prefer to manually enumerate them passively. My first step was using Shodan to look for related domains via a shared SSL certificate (I explained this technique in my previous OTP Leak article). Unfortunately, that didn't return anything useful. Next, I turned to Google dorks. The simplest dork for finding subdomains of any site is:

site:"*.target.com"

But over the years, I've noticed something interesting about Google dorks. A while back, I experimented by adding more than one asterisk (*) in my queries, and Google returned domains that didn't show up when I used just a single *.

For example, using a dork like this:

site:*.*.target.com

gave me fresh results, including deeper subdomains like:

internal.help.target.com
dev.partner.target.com

You can keep adding more asterisks to uncover even more nested subdomains (sub-sub-sub domains). It's a simple trick that often reveals assets missed by basic enumeration.

site:"*.*.target.com"
None
sub-sub domain enumeration

Since my goal was to uncover STAGING, UAT, TEST, PREPROD, or DEV environments, I refined my Google dorks to target those keywords. These environments often have weaker security controls or even allow signups, making them valuable for further testing.

site:"*stg*.target.com"
site:"*-stg.target.*"
site:"*stg-*.target.com"
site:"*uat*.target.*"
site:"*.dev*.target.*"
site:"preprod.*.target.*"
site:"*.target.*" inurl:"staging"
site:"*.target.*" inurl:"uat"
...

(You can try your own combos using the uat, stg, stage, dev, test, etc words)

While refining my dorks, I stumbled upon two staging subdomains. One of them turned out to be an admin staging environment for a React app, and it looked almost identical to the main target application I was testing. The key difference? This staging version had a Sign-Up button, something the production app didn't allow.

None
Enumerating Staging sub-domains of target

ADMIN Stage Reveals More

I quickly signed up on the admin staging interface. Most of the features were broken, and the app contained test data like dummy teams and users. Despite that, I noticed something interesting: admins had the ability to manage all teams in the workspace.

When you select a specific team, the app fires three API requests to fetch detailed information about that team:

/api/v1/<workspace-UUID>/teams/<team-UUID>
/api/v1/<workspace-UUID>/teams/<team-UUID>/cyqxqz-test/members
/api/v1/<workspace-UUID>/teams/<team-UUID>/cyqxqz-test/secrets

The Exploit

I simply replayed these API endpoints in the target's application I am testing but it failed. So, I decided to remove the test part from the endpoints, and it worked, I was able to retrieve Team member list, which contained detailed user info, and then the secrets which were encrypted ciphers.

/api/v1/<workspace-UUID>/teams/<team-UUID>/cyqxqz/members
/api/v1/<workspace-UUID>/teams/<team-UUID>/cyqxqz/secrets

Impact & Payment

Since this platform is designed for sharing documents and secrets, any information or activity by other users should remain confidential unless explicitly marked as public. This exploit allowed me to access sensitive data through an API endpoint that should have been restricted to admins only.

Again, a shameless plug: You can easily make a $150 bounty whenever you see any SSO application.

Alright, so I reported the issue responsibly and was rewarded $1,500 for the finding.

None
Getting $paid$

Hey heybye

None
Mr. Marsh

Thanks for reading this, if you have any questions, you can DM me on X @tinopreter. Connect with me on LinkedIn Clement Osei-Somuah.