Eternal · Report #938021
Availing Zomato gold by using a random third-party `wallet_id`
Summary
We received a report from @pandaaaa wherein he demonstrated a way to avail Zomato Gold membership using random Zomato User's wallet. The report was triaged and rewarded with critical severity with a CVSS score of 9.3.
It was considered critical since a random user's wallet could have been used for unauthorized membership purchases. This was only possible on third party wallets with status - active flag.
| Timeline | Action |
|---|---|
| Thu, 23 July 2020, 15:54 IST | @pandaaaa submitted a report with high severity |
| Thu, 23 July 2020, 16:08 IST | Investigation started, the team started analysing the issue |
| Thu, 23 July 2020, 16:47 IST | First contact on Report |
| Thu, 23 July 2020, 16:51 IST | Security Team reproduced the issue |
| Thu, 23 July 2020, 16:54 IST | Internal ticket logged and assigned to the Engineering Team |
| Thu, 23 July 2020, 16:54 IST | Severity upgraded from high to critical (9.3 CVSS) by Security team |
| Thu, 23 July 2020, 17:01 IST | Report triaged |
| Thu, 23 July 2020, 17:12 IST | Bounty rewarded to @pandaaaa |
| Thu, 23 July 2020, 18:11 IST | Fix deployed on production |
| Thu, 23 July 2020, 18:49 IST | Re-test requested from @pandaaaa to validate the fix |
| Thu, 23 July 2020, 20:03 IST | The researcher confirmed the fix |
Response time for this report:
- Investigation started within 14 minutes
- Reproduced within 59 minutes
- Triaged within 1 hour, 7 minutes
- Rewarded within 1 hour, 12 minutes
- Fixed within 2 hours, 17 minutes
Background
In Zomato, each user has multiple payment types, one of such payment type is third-party wallets. While purchasing Gold, the user can select the Payment method, if a user selects wallets as payment type, the user can select any of the wallets and the wallet is passed on to the backend, here, there was no check to associate wallet id with the user id, so it was possible to use other user's wallet id.
Root cause Analysis
This was introduced because of a recent code change that went live 13 hours ago.
-
Zomato allows users to avail Gold membership which is being handled by this particular request
https://www.zomato.com/php/pk_handler.php. -
To successfully purchase the membership, a series of calls are needed to be processed in a particular order.
-
In the First call, user phone number and membership price is sent
case=getpaymentsdataphone=XXXXXXXcart_value=999.00service_type=REDonline_payments_flag=1country_id=X
it then returns all the payment methods available and the last payment method used for a user.
- For the relevance of this report, only payment methods of
wallet_typeasthird_party_walletandstatusasactiveare needed.
{ "wallet_id": 8XXXXXXX3, "balance": 0.01, "currency": "INR", "user_id": "14XXXXX2", "entity_id": "14XXXX2", "entity_type": "user", "country_id": 1, "status": "active", "vault": "paytm", "storage_state": "retained", "reference_id": XXXXXXXXX, "phone": "XXXXXXXXX", "email": "[email protected]", "expires": XXXXXXXXX, "balance_display": "₹0.01", "max_recharge_amount": XXXXXXXXXX, "wallet_type": "third_party_wallet", "img_url": "https://b.zmtcdn.com/payments/wallet-logos/paytm.png", "display_text": "Paytm", "recharge_available": 1}
- On the next call, Payment type selected is used to perform the actual transaction on
https://www.zomato.com/php/red/desktop_payments_handler.php
payment_method_id=8XXXXXX1payment_method_type=walletphone=XXXXXXXXXXXXXXXXXcartValue=999.00voucher_code=action=paymentis_renewal=0user_id=1XXXXX2tnc_accepted=false
which returns
{ "status": "success", "track_id": "ZRD-XXXXXXXXXXXX", "response_message": "Capture Successful", "message": "", "code": 0, "subscription_id": XXXXXXX, "amount": 999, "city_id": 1, "upgrade_plan_flag": 0, "restart_subscription_flag": 0, "transaction_id": XXXXXXXXX, "thankyou_page_type": "thankyou_inactive", "text": "You are now a Zomato Gold member", "redirect_url": "https://www.zomato.com/gold/payment-success?subscription_id=XXXXXX&user_id=XXXXXXXX&is_first_time=1&order_id=XXXXXXX"}
- There was no check while performing the transaction to validate if the
wallet idactually belonged to the user who initiated the call.
Remediation
-
Since it could have allowed to use any random user's
wallet_idto purchase a Gold membership, the first thing we did was to investigate and see if it was abused since the introduction of this vulnerability. -
We found no evidence of it being abused apart from
2 transactionswherein both of them were test transactions to actually validate/test the issue, one was from @pandaaaa and the other one was from our internal team. -
Our engineers immediately patched the issue and the patch was pushed to production within 2 hours and 17 mins` from the report.
Thanks, @pandaaaa for helping us keep @zomato secure.
Zomato Security Team
How it was found
The write-up for this report has not been downloaded yet, or the program disclosed it without one. Read it on HackerOne.