How i was able to exploit a vulnerable payment system.


Hello hackers and security enthusiasts, we are here again to serve you dinner in a 5-star hotel 😊. Hope you enjoy it !!!.
LITTLE BIO ABOUT ME
I’m David, a software developer and cybersecurity researcher who specializes in application security. I spend my time writing secure backend code, breaking stuff in CTFs (mostly on HackTheBox), and hunting bugs in real-world applications. My stack revolves around Python, PHP (Laravel), and JavaScript. I’ve got a thing for logic flaws and money-related vulnerabilities.
ABOUT THE PLATFORM.
So here’s the gist…
The platform is a basic E-commerce application — let’s call it redacted.com
. It sells physical products, PDFs, and other digital content. Pretty standard stuff: registration/login pages, product listings, shopping cart, checkout… but there’s a digital wallet integrated into the platform.
Now that wallet system is where things start to get interesting — and vulnerable. 👀
Every user, on account creation, gets a wallet assigned to them. This wallet can be topped up via different payment gateways. Once the payment is confirmed, the backend adds the corresponding amount to the user’s wallet balance.
🔥 Now let’s get into the juice — a real-world insecure implementation I found:
After successful payment, the app hits a backend endpoint like this:
POST /api/wallet/topup
Content-Type: application/json
{
"user_id": 124,
"amount": 100.00
}
No token. No signature. No validation that the request actually came from the payment gateway.
That’s it. Just a raw unauthenticated endpoint that increases the balance based on whatever payload you throw at it.
So guess what? Once I saw that, I immediately fired up Burp Suite and replayed the same request over and over. 💰💰💰
Result? My wallet balance went up every single time.
This is what we call a logic flaw. The server blindly trusts that any incoming user_id
and amount
must be valid. It assumes the client only calls this endpoint after a legit payment — but it doesn’t actually verify that with the gateway or check for replay. I can actually tamper the user_id
value and add balance to a different user, because from the look of things, the user_id
is an incremental integer.
🔍 What Should’ve Been Done?
At the very least:
The endpoint should validate the payment with the third-party gateway (e.g., verify transaction ID with Paystack, Flutterwave, Stripe, etc.).
There should be server-side verification, not client-side trust.
Idempotency: each payment transaction should only be processed once.
Use proper auth & signatures to ensure requests originate from the gateway or trusted service.
😎
We break codes, not hearts. 💔💻❤️
Subscribe to my newsletter
Read articles from Zalparus directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Zalparus
Zalparus
I develop secured software and also perform actively in cybersecurity researches