If you've ever booked a "non-refundable" hotel room, you know that feeling of dread when your plans change. You're locked in. The money is gone.

Well, last month, I found out that for one of the world's largest travel booking platforms, "non-refundable" was actually just a suggestion. It took me three days of digging, but once I found the thread, the whole sweater unraveled.

The Setup: Hunting in the "Post-Request" Fog

I was testing a private program on Bugcrowd. The target was a massive travel aggregator. I'd spent hours looking at their payment gateway (nothing) and their user profiles (boring).

I decided to look at the Cancellation Flow.

When you cancel a "Non-Refundable" room, the UI shows a big red box: "Warning: You will receive $0.00 back." When you click 'Confirm,' the browser sends a POST request to the server.

The "Stupid" Idea

I intercepted the cancellation request in Burp Suite. It looked standard:

POST /api/v1/cancel-booking

{"booking_id": "XYZ-123", "confirm": true}

I looked at the response from the server. It returned a JSON object containing the booking details and a field called refund_amount: 0.

Then I had a thought: What if I told the server how much I wanted back?

I re-sent the cancellation request, but I manually added a parameter that wasn't there before. I guessed the name based on the response field.

POST /api/v1/cancel-booking

{"booking_id": "XYZ-123", "confirm": true, "refund_amount": 500}

The "No Way" Moment

The server responded: 200 OK.

I refreshed my "My Bookings" page. The status had changed to Cancelled, and the UI said: "Refund of $500.00 is being processed to your original payment method."

I sat there staring at the screen. I had just turned a $0 refund into a $500 refund by simply asking for it.

I tried it again on a different test booking. This time, I got greedy. The booking cost $200. I sent refund_amount: 5000.

The server accepted it. I had found a Parameter Injection flaw that essentially allowed me to print money from the company's bank account.

The Payday

This was a Priority 1 vulnerability. If a malicious actor found this, they could have automated the cancellation of thousands of bookings, requesting $10,000 refunds on $100 rooms, potentially bankrupting the company in a weekend.

Milestone The Reality Time to Find — 72 hours of boredom, 30 seconds of "what if"

Severity — Critical (Financial Impact)

Bounty Awarded — $12,000

The security team didn't even wait for the weekly triage meeting. I had a "High Five" email and a bounty confirmation in my inbox within six hours.

The Takeaway for My Fellow Hunters

If you want to hit the five-figure bounties, stop looking for "hacker" stuff. Start looking for Logic Flaws.

  • Guess the Parameters: Developers often use the same names for variables in the frontend and backend. If you see discount_total in a response, try sending it in a request.
  • The "Double-Blind" Test: Does the server trust the client (the browser)? If the answer is yes, that's where the money is.
  • Don't overcomplicate it: Sometimes the front door is locked, but the "Cancel" button is wide open.

Bug hunting isn't about being the smartest person in the room; it's about being the most curious. Keep poking the box until it breaks.

𝒯𝒶𝓃𝓋𝒾 ♡