Hacking E-Commerce For $$$: IDOR and More

2 weeks ago 22
BOOK THIS SPACE FOR AD
ARTICLE AD

Hashim Amin

Hello Friend, this is mrhashimamin. It’s been a while since we last talked. After a few days of feeling frustrated with bug bounty because of my last informative report, I decided to try another public program on Bugcrowd. It was a bit harder, but I learned a lot (we’ll get into that in another write-up; just updating you with the latest).

Anyway, after running into a lot of duplicates and N/As, I made a new friend on Facebook who has a private program on HackerOne. Let’s call it thegoodshop.com.

thegoodshop homepage

It’s a simple e-commerce app for used products. You can add items to your cart and buy them, or bid on live auctions, then pay and get your item.

No, no, it’s not what you think. I’m not that newbie hacker anymore xD. Let me tell you the story behind this, starting with the main auth functions: testing sign-in, sign-up, password reset, and OAuth. My friend pointed out something interesting: “The reset tokens don’t expire — how can we make that useful?”

Digging a bit deeper, we found that reset tokens don’t expire until you request a new one. So, what’s the big deal? Well, we decided to change the email address on one of our test accounts, then tried to use the old reset token. And guess what? It worked!

So, we came up with a pretty cool scenario:

1- When Victim creates an account, he receives a reset/create password link in his registered email.
2- The victim changes their email to a new one (e.g., from victim@old.com to victim@new.com) because victim knows that that the attacker has access to their old email address.
3- Attacker, who already has access to the latest password reset link sent to victim@old.com, uses this link to reset the password.
4- The attacker successfully changes the victim’s password.

Yeah, at first, we thought they might close it as informative or N/A, but they actually accepted it as low. Nice catch, since the scenario was a little bit realistic.

After a couple of days, I focused on other functions: add to cart, complete order, and view purchases.

Let me explain the purchasing process for you:

1- A good user sees a product they want, so they add it to their cart.

2- To complete the purchase, he click on complete order.

3- Now, the product is in the purchases list for the user, and they have to pay for it — otherwise, their account could be blocked for having uncommitted purchases.

So, how thegoodshop.com knows about the uncomitted purchases or how it actually happens?

In step 3, Before you pay for the product. A POST request is sent to the endpoint /api/webapi/shopping/ordercheckout/createuncommittedpurchaseorder to mark this order as uncommitted untill u pay for it.

But here’s the thing, if u send this request more than once:

1- The purchase will disappear from your account, so you won’t be able to pay for it later.

2- After a while, your account will get blocked for having too many uncommitted purchases.

POST request body

So, I made another order with my second account and replaced the purchaseOrderId with the one from the other account. And it worked!

But there was such a thing: the program’s policy stated that any IDOR depending on GUID/UUID would be changed to low severity. So, I challenged myself, thinking, “You really need to find this Id” And that’s exactly what happened.

I crawled the website, ran through some purchasing functions as a regular user, and went back to my Burp history. I searched for purchaseOrderId — and found exactly what I wanted. Another vulnerable parameter for IDOR!

How i got the purchaseOrderId?

When you attempt to purchase a product, a transactionId is generated and tied to the purchaseOrderId. When you try to complete this purchase, the application sends a GET request to this endpoint with the transactionId to retrieve the purchaseOrderId, and then it uses that ID to complete the process.

So, my attack scenario was like this:

Making a simple Python script or using macros and Intruder in Burp Suite to get any valid transactionId (0:999999999), retrieve all purchaseOrderIds, and then uncommit/stop any purchase order on thegoodshop.com.

At first, I thought blocking user accounts was automated only based on having uncommitted purchases, but they mentioned that it’s controlled manually by them. However, we reported this as critical xD, but they accepted it as medium. Anyway, we’re good with that.

Read Entire Article