Reverse Engineering Bumble’s API

When you have too much time on your hands and want to dump out Bumble’s entire user base and bypass paying for premium Bumble Boost features.

Sanjana Sarda
Independent Security Evaluators

--

As part of ISE Labs’ research into popular dating apps (see more here), we looked at Bumble’s web application and API. Continue reading as we will demonstrate how an attacker can bypass paying for access to some of Bumble Boost’s premium features. If that doesn’t seem interesting enough, learn how an attacker can dump Bumble’s entire user-base with basic user information and pictures even if the attacker is an unverified user with a locked account. Spoiler alert — ghosting is definitely a thing.

Updates As of November 1, 2020, all the attacks mentioned in this blog still worked. When retesting for the following issues on November 11, 2020, certain issues had been partially mitigated. Bumble is no longer using sequential user ids and has updated its previous encryption scheme. This means that an attacker cannot dump Bumble’s entire user base anymore using the attack as described here. The API request does not provide distance in miles anymore — so tracking location via triangulation is no longer a possibility using this endpoint’s data response. An attacker can still use the endpoint to obtain information such as Facebook likes, pictures, and other profile information such as dating interests. This still works for an unvalidated, locked-out user, so an attacker can make unlimited fake accounts to dump user data. However, attackers can only do this for encrypted ids that they already have (which are made available for people near you). It is likely that Bumble will fix this too within the next few days. The attacks on bypassing payment for Bumble’s other premium features still work.

This research was covered by Forbes.

Reverse Engineering REST APIs

Developers use REST APIs to dictate how different parts of an application communicate with each other and can be configured to allow client-side applications to access data from internal servers and perform actions. For example, operations such as swiping on users, paying for premium features, and accessing user photos, occur via requests to Bumble’s API.

Since REST calls are stateless, it is important for each endpoint to check whether the request issuer is authorized to perform a given action. Additionally, even if client-side applications don’t normally send dangerous requests, attackers can automate and manipulate API calls to perform unintended actions and retrieve unauthorized data. This explains some of the potential flaws with Bumble’s API involving excessive data exposure and a lack of rate-limiting.

Since Bumble’s API is not publicly documented, we must reverse engineer their API calls to understand how the system treats user data and client-side requests, especially since our end goal is to trigger unintentional data leakage.

Normally, the first step would be to intercept the HTTP requests sent from the Bumble mobile app. However, since Bumble has a web application and shares the same API scheme as the mobile app, we’re going to take the easy route and intercept all incoming and outgoing requests through Burp Suite.

Exploring Bumble Boost

Bumble “Boost” premium services cost $9.99 per week. We will be focusing on finding workarounds for the following Boost features:

  1. Unlimited Votes
  2. Backtrack
  3. Beeline
  4. Unlimited Advanced Filtering — except we are also curious about ALL of Bumble’s active users, their interests, the kind of people they are interested in, and whether we can potentially triangulate their locations.

Unlimited Votes

Bumble’s mobile app has a limit on the number of right swipes (votes) you can use during the day. Once users hit their daily swipe limit (approximately 100 right swipes), they have to wait 24 hours for their swipes to reset and to be shown new potential matches. Votes are processed using the following request through the SERVER_ENCOUNTERS_VOTE user action where if:

  • “vote”: 1 — The user has not voted.
  • “vote”: 2 — The user has swiped right on the user with the person_id
  • “vote”: 3 — The user has swiped left on the user with the person_id
SERVER_ENCOUNTERS_VOTE endpoint

On further examination, the only check on the swipe limit is through the mobile front-end which means that there is no check on the actual API request. As there is no check on the web application front-end, using the web application instead of the mobile app implies that users won’t ever run out of swipes. This peculiar frontend access control method introduces the other Bumble issues in this blog — several API endpoints are processed unchecked by the server.

Backtrack

Accidentally swiped left on someone? This is no longer an issue and you definitely don’t need Backtrack to undo your left swipe. Why? The SERVER_ENCOUNTERS_VOTE user action does not check if you have previously voted on someone. This means that if you send the API voting request directly, changing the “vote”: 3 parameter to “vote”: 2 you can “swipe right” on the user of your choice. This also means that users don’t have to worry about missed connections from 6 months ago because the API logic does not perform any sort of time check.

Beeline Part I

The Beeline is one of the main features of Bumble Boost as it allows users to view all the people who have swiped right on them.

When we studied the network traffic using the Developer Console, we found a SERVER_GET_ENCOUNTERS endpoint that displays all the users in our potential match feed. What’s interesting to note though, is that it also displays their vote and we can use this to differentiate between users who haven’t voted versus users who have swiped right.

SERVER_GET_ENCOUNTERS endpoint with “their_vote” field

The only problem with this method of finding admirers is that if the developers decide to fix this automatic voting disclosure, we will be lost and lonely. Our next step is to try to figure out how the endpoint has the vote value in its response so that we can recreate this behavior for other requests. Hopefully, we will be able to do this by studying the original request below.

SERVER_GET_ENCOUNTERS Generated Request

The most interesting thing about this request is the various numbers in the user_field_filter projection field. Now, our goal is to figure out what these numbers really mean.

The Secret Worker Bee

Even before we started intercepting Bumble’s requests, we discovered a bumble-service-worker.js file while exploring the web application using the Developer Console.

bumble-service-worker.js

Service workers are event-driven JavaScript worker files that control the site they are associated with and control how network requests are handled. These files are also responsible for background syncs.

On exploring this file we found several interesting key pairs such as those for User Fields (shown below — yellow highlights show explore-worthy fields), User Actions, Error Codes, and Feature Type Permissions.

bumble-service-worker.js UserFields

Bumble APK

Okay, but what if you are super determined to only use the mobile app? We can use dex2jar to extract smali classes and other files from the Bumble APK and grep for similar information. For example, we used grep -i -r “USER_FIELD” to find the location of all the User Fields and their constant values. The following image shows the constant for USER_FIELD_IS_HOT (0x104) which is the hex for 260.

smali_classes2/com/badoo/mobile/model/wx.1.smali

Beeline Part II

Now that we know that the code for “their_vote” is 560 and “my_vote” is 550, we can force the request for the SERVER_GET_USER endpoint that retrieves user data to include this information for a specific user (this method can also potentially be used for other endpoints).

SERVER_GET_USER with additional 550 and 560 user field parameters

Unlimited Additional Filtering via User Enumeration

The last Boost feature that we will be “emulating” is the ability to find users using unlimited additional filters. However, we shall do this by enumerating Bumble’s users all around the world (except users with deleted accounts), using the SERVER_GET_USER endpoint with additional user fields, and separating this information in a spreadsheet. We can then filter for the features we are looking for via the following script which you can use, for example, to find all the users within 10 miles of your current location.

Disclaimer — please don’t use this script to do nefarious things, it has been made strictly for educational purposes and as a proof of concept.

Python Script to Dump Bumble User Information

The album field consists of all pictures uploaded to the app by a user (370). If an account is connected to Facebook, you can retrieve all of their “interests” or pages they have liked (420).

The “wish” field tells you what they are doing on the app and the exact kind of people they are looking for (360).

The “profile” fields provide information such as their descriptions, education, height, smoking and drinking preferences, voting status, political preference, religious beliefs, and zodiac (this information is technically already displayed by the application)(490).

Other interesting information is if they have the “mobile application installed” (680), if they are “hot” (260 )(still have not found anyone who Bumble thinks is hot), if they are “online” (330), and their “distance in miles” if they are from the same city (530)(since attackers can easily spoof their location, triangulation is definitely a possibility). Something to note, the request requires a User-Agent header for the short distance in miles to show up. For a better idea of the information you can retrieve, here is a sample user response.

Sample Response from SERVER_GET_USER

Our accounts eventually got locked and hidden for more verification requirements. We tested retrieving user data while our account was locked, and it still worked. So even though other endpoints such as SERVER_ENCOUNTERS_VOTE check for locked users, the SERVER_GET_USER endpoint does not.

This script works as Bumble has not enabled rate limiting on their API and instead of only using the encrypted_user_ids, Bumble allows users to be accessed by their actual user_ids which are sequential (approximately 0 to 2,000,000,000).

Conclusion

Most of the issues in this blog stem from Bumble not verifying requests server-side. Due to this, advanced users can bypass Bumble’s main premium features easily through the web application, and attackers can collect detailed information about Bumble users.

Coordinated Disclosure Timeline

  • March 30, 2020: ISE’s initial contact disclosing vulnerabilities on HackerOne
  • March 31, 2020: Report triaged on HackerOne
  • June 16, 2020: ISE’s second contact sent via HackerOne asking for Updates — No response.
  • July 9, 2020: ISE’s third contact mentioning our public disclosure plan sent to Bumble’s feedback email — No response.
  • July 10, 2020: ISE’s fourth contact sent to Bumble’s partnership form — No response.
  • November 12, 2020: Report resolved on HackerOne.

Bumble has not responded to any of ISE’s direct contact attempts.

Sign up to get our latest blogs.

Sanjana Sarda is a Junior Security Analyst at Independent Security Evaluators, a firm of security specialists that provide a wide range of services including custom security assessments and software development. ISE also runs IoT Village, which hosts talks by expert security researchers who dissect real-world exploits and hacking contests consisting of off-the-shelf IoT devices.

Twitter: @ISESecurity

--

--