A story about how my friend and I got more than 20K USD around 1,5 month from IDOR, XSS, CSRF, and more

YoKo Kho
YoKo Kho
Sep 21 · Unlisted

بسم الله الرحمن الرحيم

- This isn’t a series article of my previous one. This one is only one part. –

This simple article will cover few basic vulnerabilities write-up at one target such as:

• Information Disclosure via Google Dork
• A Simple Bypass of Registration Activation
• A Simple IDOR; and
• Escalating CSRF to medium severity (from POST to GET Method)

As a piece of information, for sure, this simple write-up didn’t talk about much of new things. It just uses some of the basic technique that may be forgettable for much of bug hunter/researcher.


Before we go to the technical detail, then I think the readers should know the main reason why I choosing this target at one of the private bug bounty program (and hopefully it could be useful for the other).

At the end of 2017, I was invited to the one of a private bug bounty program. When I saw the total “reported issues” has reached almost 1,000 with a limited scope - main domain and few subdomain while few of them are blogs - then I really have lost my interest to participate. (Yes, it similar with my words at another article).

But, one day at early 2018, I try to come back to this program. I tried to looking at the scope carefully and thinking it clearly about the target that maybe vulnerable. In short, I choose one of the subdomain (of course not the blog), then trying to get some information from using the Google Dork. After a few minutes, I got a URL pattern related to the target and try to use it with another dork. And finally, I could enumerate around 50 transactions without the needs of valid username and password.

I reported the issue to the program and got 100 USD . Yes, its normal since the transaction that could be enumerated is only around 50.

Then, in 2019, I go to this program again (please, don’t ask why). Then, I saw the number of “reported issues” does not increase significantly, maybe it around 20 or 30 reports. Then, I said: “why we are not giving it a try and more focus on the specific target?

So, I go to the same target and trying to find a way to bypass the registration activation. Finally, I got 4 findings that lead me got few thousands USD. Then more and more (I do a collaboration with one of my friend - Tomi), and finally, Alhamdulillah - with the permission of Allah, we got around 20,000 USD within 1,5 month from only one target (He got more than 10,000 USD).


2.1. Few Words about this Write-Up

As a piece of information, for sure, this simple write-up didn’t talk about much of new things. It just uses some of the basic technique that may be forgettable for much of bug hunter/researcher.

Start from the registration activation bypass, a little “formal registration” to get the formal access, then finally much of IDOR issue that lead to several things such as blocking the account, accessing the transaction report, generate the transaction report, and also much more (including the issue such as stored XSS, Escalating CSRF from POST to GET Method, and other).

2.2. Simple Summary

We realize if some reader maybe feels more comfortable with a summary. Then in this section, we will explain the whole summary related our “journey” about this topic.

2.2.1. At 2018 ago, the keyword that I used on Google while looking at the target information is: “github.com subdomain.targetname.com”. From the result, finally I found a pattern at the 1st page like:


The next thing that I do is using a simple Google Dork with the hope could enumerate something, for example:

site:subdomain.targetname.com AND inurl:trNum=

Then I change the “trNum=” with “trNum”, “e=”, and “e”. It could gives the various result and enough to enumerate around 50 transactions.

Reported the issue, and was triaged and rewarded with 100 USD.

As a note, the trNum contain around 10 unique numbers. If the trNum is not had any relation with the email, then the transaction report can’t be open.

2.2.2. At 2019, I tried to register my own account with common free email. Then the application shows information if I should wait for approval and after that, I will get the password. It still shows the same thing that I faced 2018 ago.

At this situation, my heart was moved to used the reset password feature and surprisingly, I got a unique URL for resetting my own password (which is the account still don’t have a password and isn’t activated yet). I clicked the URL and got redirected to the prompt that could be used to put my password. The next thing, I put the password and I was able to login with the account without need any approval.

Another report has been triaged and rewarded for this issue. The reason is that I have no ability to execute many things with this level of accountability. Well, interesting. From this reply, I finally know if this application is actively using by many people so I should be digging deeper.

2.2.3. Since I could log in and just could accessing my own profile, then I tried to update my own account and try to look the parameter that sent by the application (as a simple description, two of them is a “unique ID” and “email ID” parameter). From here, then I change my email address to another email address that I registered too, with the hope I could found an account takeover issue. (yes, also try the parameter pollution).

So sad, I didn’t find an account takeover. But the good thing is, by using this way, I found out the issue that could be blocking permanently the other account. Because there is a collision from one unique ID having two email ID, then both of email can’t be used to log in anymore without changing it directly at the administrator dashboard or database. I report the issue, then it was triaged and rewarded again.

2.2.4. I go back into my report at 2018 and I found if the issue was stated as resolved. In this case, I tried to reproduce the same issue with the same technique. Then I find out if the transaction report can’t be seen again by using this technique, which is, a user needs a valid session to get the access into the report.

But the good thing is, I still could see the value at the email parameter. So, again, I found 50 different email address by using the same issue (similar to previous, but at this time, just an email address).

Trying to reported again, and got triaged and rewarded.

2.2.5. After thinking that I already done it most of the one that I know in this limited access of account, then I tried to register the account again. The difference is, I tried to put my own corporate email (a corporate that I working for).

To be honest, at one of the field, there is a something like a unique number that highly possibility is relates to the transaction code that has been received by the valid customer.

So, basically, I try to find out the model of unique number and I have no idea since no one that put it to public (search engine give no good result, or at least, I don’t know how to optimize the keyword).

Well, with the hope of my account got an approval, then, I continue the registration with a random number.

Why I really want to get the access internally into this site? Because I’m sure that no bug hunter touch this site yet. Please kindly see my reason why I give it a “try again” at this program (the report only increase around 20 - 30 reports in around one year - totally different with the result that they got from few years before that could reach 150 - 250 reports). And the other reason, because I found the valid “registration activation bypass” and the “blocking account” issue at this portal.

Surprisingly, 3 days after the registration is submitted, I got an email that showing if my account has been approved and could login. I setup the password from the sent unique URL, then login directly into the portal. And I’m really happy when I see so much of menu inside of the application.

At that time, I doing a simple test to one of the menu that could be used to accessing my own transaction (which is something that I never done). In short, generally the application send a transaction ID parameter to server (without any token at the header and POST Data) when we request this kind of data.

With the hope if there is an IDOR, then I changed those transaction ID number to the random one. Finally, I got what I want. By using this trick, I could accessing much of customer data without the needs of username and password.

I report the issue, then it was triaged and rewarded.

The next is, I collaborate with my friend and found much of issues at this portal that worth with total of more than 20,000 USD.

So, this is the end of the summary. At the next section, I will try to explain the technical detail with some of other issue such as escalating CSRF from low to medium severity (as a note, the Stored XSS write-up has been released at Tomi’s Medium).


At this section, we will try to explain few step by step about this story.

3.1. Simple Information Disclosure via Google Dork

With the limitation of the access (for example we just could face the login form only) and in case we didn’t found any flaw at the application, then few things that we could do are:

  • Trying to crawling the directory (much tools that we could use, but personally I use dirsearch for helping me)
  • Looking for the information related the application (such as found the flow that executed in URL) via search engine (much of resources and one of them is GitHub).
  • And maybe few more.

Before we go more further, then lets see the background about how we could execute this simple technique.

3.1.1. Few words about the use of Search Engine to Finding a Possible “Leakage”

Quoted from our other article (about 1,000 USD for simple information disclosure at PayPal):

We can’t deny if one of the biggest dream for everyone that has so many contents at their site is to be indexed at top search engine in the world. In reality, we should realize that even the search engine could help us to “promote” our contents to public, the search engine itself could “betrayed” the site owner to leakage the information if those site owners doesn’t setup the blocking rules properly.

This kind of mindset was coming out with a good fact by the research that has been conducted by Ateeq Khan. At November 2013, he has shown the interesting vulnerability (Critical Information Disclosure) that exist at Microsoft Yammer product by using the main function of the search engine. With the “leakage” of token that has been indexed “accidentally” by search engine, then the Attacker at that time could use those information to login to the related account.

3.1.2. How Finally We Execute this?

From those mindset, then we start to digging at search engine. One of the keyword that we used at Google is: “github.com subdomain.targetname.com”. From this activity, we found a github page at the 1st page that contain a pattern like this: subdomain.targetname.com/Detail?trNum=${TRANSACTION_NUMBER}&e=${EMAIL}.

As explained earlier, the next thing that wedo is using a simple Google Dork with the hope could enumerate something because they didn’t setup the bots prevention yet, for example:

- site:subdomain.targetname.com AND inurl:trNum=
- site:subdomain.targetname.com AND inurl:e=
- site:subdomain.targetname.com AND inurl:trNum
- site:subdomain.targetname.com AND inurl:e

As we could see, two of them are use “=” and two of them not. We don’t know why, but somehow it gives different result.

At this point, then we could see the URL and could see the transaction (at 2018) and still could see the email value (At 2019).

3.1.3. Why it could happened?

Well, we can’t explained technically. But from what we’ve learned from the other program owner, commonly it happened because the application didn’t setup a noindex meta tag.

So, for preventing the search engine to index this type of request, the developer should use the noindex meta tag in the page. Google at its documentation has telling the other way to prevent the search engine to index this kind of method.

Block search indexing with ‘noindex’

Also HubSpot from one of their article has telling the two effective ways to preventing the search engine to index our content that could be sensitive or not useful.

3.2. Simple Registration Activation Bypass by Using Reset Password Feature

The lucky thing for us related this application is we could registering ourselves, even though we still need an approval.

Please kindly note, since it also just a simple way, so we won’t described the parameter that sent from this activity.

Basically, we just fill the things at the registration form. We fill the name, company name, email address, and every needed data. After the request has been submitted, then we got an information if we should wait for an approval.

While waiting an approval that we’re sure if my account won’t get approved (since we using the account from free email address service), then we tried the reset password feature.

Surprisingly, the application sending us the URL that could be used to setup the password.

You can click the link below to setup your password:

Please don’t reply to this email if you have any questions or issues.

At the first time, we’re not sure if the account is active even though we use those URL and put the password. But when we tried to login, we finally got an access into the portal.

3.3. IDOR with The Ability to Blocking the Other Account Permanently

After got an access into the portal, the only menu that we could access is our own profile. At this situation, we just could update our common information (such as first and last name, company name, position, and few more). As could be seen, email is the parameter that we couldn’t change.

By seeing this situation, then we tried to conduct an account take over scenario. In short, when we submit our update to server, then the application will send a request with several parameter such as:

POST /account/user/update
Host: subdomain.target.com
lang=en&id=hash_here&email=email_here&____and more____

Even though they put a unique hash at the POST parameter, then we still trying to change the email address into another one.

The detail is, we change the “email” parameter value from the 1st account into the 2nd account that we also created with the same way.

Original: lang=en&id=hash_here&email=1stemail&____and more____
Modify: lang=en&id=hash_here&email=2ndemail&____and more____

But as expected, the account takeover is not happened because we can’t login with the password that we setup for the 1st account.

Then, we tried to login into the 2nd account with its valid password. And the result is, we can’t login. At the first time, we thought that we forget the password of the 2nd account. But then, after resetting its password and put the new one, we still not be able to login anymore.

From this analysis, we assume if the previous activity has block the access of this 2nd account. For make our assumption goes right, then we reproduce the issue once more with the 3rd and 4th account. And the result is success. We are able to blocking the other account (and our account also has been block by this execution).

3.3.1. Why it could happened — The block one?

Well, simply we think that because the mandatory parameter at their database is those ID parameter that contain the unique hash. So, when one unique ID has two same value of email, then the application can’t decide which one is correct. Then the application “decide” to block both of this account.

3.4. IDOR that could Lead to Accessing Other Detail Transaction Report

For sure, this one also not a new one for much of bug hunter / researcher that actively hunting. But for completing the explanation about the 1st four vulnerabilities that lead us to many bug, then we thinks it’s worth to share.

3.4.1. Trying to Register with Valid Corporate Account

While we are stuck about the things that could be done with those level of account (limited access), then we start to registering the new account with corporate email.

As we said earlier, there is a kind of transaction number that we should fill at the registration process. High possibility if this number could be got by its user by doing a valid transaction at the other portal. Here is the sample flow that we learned from this application:

The Normal Flow

Since we have no idea about the looks of those unique number, then we start to insert the random number with the hope if our request got an approval.

3 days later after the request has been submitted, then suddenly we got a very nice email:

Your account has been created.

Please click the following hyperlink to activate and log in to your account:

Once you log in, please set your password as soon as possible.

After click those URL and put the password, then we tried to login and finally we could see much of menu that could be test.

3.4.2. The IDOR Execution — Seeing other Transaction Data

After login into the site, then we start to test one menu, which is looking the transaction data.

When we access the function at this menu, then the application will send a request like this:

POST /transaction/report/list
Host: subdomain.target.com

Yes, your assumption is correct. We just need to change the transactionid parameter into another value and we will get the access to other customer transaction. No Custom Header that contain a token, no token at POST data, so, it could going perfectly.

From here, then we try to find out another similar issue and we found around 15 IDOR issue at this portal (with range of bounty from 600 until 1,250 USD).

3.5. Escalating CSRF Issue from Low to Medium Severity

For sure, this one also not a new one for much of bug hunter / researcher that actively hunting. But for completing the explanation about the 1st four vulnerabilities that lead us to many bug, then we thinks it’s worth to share.

3.5.1. Few Words about CSRF

Generally, CSRF is an attack that “forces” a user to do something that is basically “unwanted” in a web based application by utilizing the circumstance of the victim that is being authorized (login). In general, this kind of attack could be used because the absence of authentication process in doing a change or the absence of unique token that is allowed to process the related matter (the uniqueness of the token is usually given so the user wouldn’t be troubled by typing password to changes that are not quite significant).

3.5.2. The Application Status

So, just like a common application, this target also has a feature to delete, share, and other (yes, we also test an IDOR at this feature).

For example, when we would like to delete or share something, then the application will send a request like this:

POST /transaction/report/delete
Host: subdomain.target.com

It also similar with the share feature. The difference is, there is an email address at the POST Data and the “delete” path at the endpoint was change into “share”.

As could be seen, not a good thing (at least for us) since this feature was execute in the POST method. The reasons because we don’t know yet how to execute a CSRF by conduct multiple action with POST method (looking for some resource, and its not work).

From this situation, then we tried to change the HTTP Method from POST to GET. (it could be changed easier by using “Change request method” feature at Burpsuite).

Change Request Method at Repeater Mode

So, it should be like this for a “delete” feature:


Surprisingly, it works (while the other function are doesn’t work with this one). Then, we directly create a simple PoC to execute the multiple deletion in one action.

For example, we would like to delete the numberID from 31337 to 31348, then simply we could embed the URL in the border-less image tag (with no height and width). Here is the sample HTML script that we use:

<img src=”https://subdomain.target.com/transaction/report/delete?numberId=31337" width=”0" height=”0" border=”0">
<img src=”https://subdomain.target.com/transaction/report/delete?numberId=31338" width=”0" height=”0" border=”0">
<img src=”https://subdomain.target.com/transaction/report/delete?numberId=31339" width=”0" height=”0" border=”0">
<img src=”https://subdomain.target.com/transaction/report/delete?numberId=31340" width=”0" height=”0" border=”0">
<img src=”https://subdomain.target.com/transaction/report/delete?numberId=31341" width=”0" height=”0" border=”0">
<img src=”https://subdomain.target.com/transaction/report/delete?numberId=31342" width=”0" height=”0" border=”0">
<img src=”https://subdomain.target.com/transaction/report/delete?numberId=31343" width=”0" height=”0" border=”0">
<img src=”https://subdomain.target.com/transaction/report/delete?numberId=31344" width=”0" height=”0" border=”0">
<img src=”https://subdomain.target.com/transaction/report/delete?numberId=31345" width=”0" height=”0" border=”0">
<img src=”https://subdomain.target.com/transaction/report/delete?numberId=31346" width=”0" height=”0" border=”0">
<img src=”https://subdomain.target.com/transaction/report/delete?numberId=31347" width=”0" height=”0" border=”0">
<img src=”https://subdomain.target.com/transaction/report/delete?numberId=31348" width=”0" height=”0" border=”0">

After the victim open the script at their browser (while they still authenticated), then all of those information will deleted.

When reporting this issue, the program owner has change the severity from low to medium.


Well, as the readers could see, maybe this one is not a good write-up. Also, there are not much new technical detail that could be learn. But we still releasing this one because we’re sure if there are much thing that we could learned from this story. Few of the good things are:

  • Always try to resetting your own password even though you didn’t get an access after the registration is complete;
  • Always try to use your corporate email account. Somehow, the application’s owner think that those registration is a valid one and could give a profitable things (from the business point of view);
  • Always try to remember how much report that has been rewarded at a program (it also useful to see how much their HoF in public program). It could be useful for us to seeing how the bug hunter / researcher interest to those program and how we could possibly exploiting the new technique at those target. I remember when Andy Gill released the write-up to executing the Illegal Rendered at Oracle EBS platform (CVE-2017–3528). He just released the issue at 2018, and we start to looking the public bug bounty program with not much of HoF and looking the target by using the simple Google Dork (site:*.target.com AND inurl:/OA_HTML/). In few hours, we got 450 USD from 2 programs.

FYI, personally, I didn’t agree if those CVE-2017–3528 was called as open redirect. From the PortSwigger explanation, it more likely an “Out-of-Band Resource Load”

  • Always go back to your old report and try to reproduce the same thing when the owner said it resolved. At the other situation, I ever reported at Reflected XSS at the used Jira in one of private program. The issue was triaged and fixed around few months. After I got an information if the issue was fixed, then I go to the same target again and I was redirected to another subdomain that using the Jira too. The difference is, while they migrated their data from Old Jira to New Jira, they forget to put the authentication to access every ticket. The result is, I could see much of confidential ticket (including the working credentials) which is lead me to got another triaged report.
  • And maybe much more thing that we don’t know yet.

InfoSec Write-ups

A collection of write-ups from the best hackers in the world on topics ranging from bug bounties and CTFs to vulnhub machines, hardware challenges and real life encounters. In a nutshell, we are the largest InfoSec publication on Medium. Powered by Hackrew


YoKo Kho

Written by

YoKo Kho

Bug Hunter | OSCP | One of 2018 BugCrowd MVP | https://twitter.com/YoKoAcc | https://bugcrowd.com/YokoKho

InfoSec Write-ups

A collection of write-ups from the best hackers in the world on topics ranging from bug bounties and CTFs to vulnhub machines, hardware challenges and real life encounters. In a nutshell, we are the largest InfoSec publication on Medium. Powered by Hackrew

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade