Hijacking shared report links in Google Data Studio

Feb 5 · 6 min read

In this blog post, I will explain the process of how I discovered an authorization flaw in Google Data Studio which allows me to gain control of shared report links.

Nezuko ❤

Google Vulnerability Reward Program

Similar to Medium and Facebook, Google hosts their own vulnerability reward program (bug bounty program) through this form. What different is that Google’s have multiple triage process when compared to other programs.

I had began my hunt in Google a fortnight ago. Most of my time was reading write ups published by researchers about vulnerabilities they found in Google. There are many awesome write ups available online which allows you to have a better understanding of how Google’s application works.

Picking the target

Interestingly, two of the write ups I read before mentions they both found vulnerabilities in the same sub-domain which is Google Data Studio.

I had linked both of the write ups below.

It then occurs to me that since a vulnerability can be found twice in the same sub-domain, will there be any chances that there are still some unseen vulnerabilities lying there?

Understanding the application

In my opinion, finding authorization flaws is about understanding how it works and attempt to outsmart it. I did spend a good time looking at the functionalities provided in Google Data Studio.

Since it had been blogged before by two researchers, I suppose spamming payloads everywhere won’t take me far. Hence, I began studying the functionalities inside it and fiddle around with it.

Discovering the issue

Google Data Studio

Firstly, I created a blank report. This is how it looked after I created it.

Observe the highlighted area

Clicking the arrow beside the Share function (highlighted in red rectangle) shows us some features we are allowed to use to share our reports, one of them is Get report link .

Get report link

As the name suggests, it creates a report link for your report by appending a string of characters after a custom endpoint.

Now, let’s intercept the request sent to server when I attempted to click the checkbox Link to your current report view .

Observing the JSON payload carefully, it’s sending two parameters which is reportId and shortLink.id with the values in red font color.

reportId : 87d41ef9–1ebc-4d92–84e7-d5948e5940ed

id : m7PKn-j4R_s

At first glance, the id parameter’s value seems to be the report link it generated when I clicked the Link to your current report view checkbox.

I began to throw a random string in the id parameter and see what happens after that.

I set the id parameter’s value as “iamsushi”

I then navigate to https://datastudio.google.com/s/iamsushi and found out it redirects to my reportId which is 87d41ef9–1ebc-4d92–84e7-d5948e5940ed. By default, users without permissions are not able to view the report unless specified otherwise.

I began to try setting the id parameter’s value with an existing value. To my surprise, the server still returns 200 OK as response.

Things had became interesting now, as the report link section was not the first authorization issue I tested. I’m actually expecting I will receive a 403 Forbidden when I set the id parameter’s value with an existing value.

To demonstrate, the Download report request returns a 403 Forbidden when I attempt to download someone else’s report.

403 Forbidden when trying to download someone else’s report

I used a simple dork to dork for existing short links online. I can conclude that I’m able to overwrite the short links found in Google dork just by changing my shortLink.id parameter’s value into theirs.

I reported to Google Vulnerability Reward Program after that explaining that a user can substitute other people’s report link and point it to his own report (after allowing global read access).

Another surprise

Another day passed and I received an email from Google stating my report was Assigned, which essentially means it’s triaged in first sight.

It should be noted that Assigned was just the first process.

I then continued to find other authorization flaws in the website and stumbled into the bug I reported.

Looking at the request twice, I realized I haven’t tested the reportId parameter.

It was dumb of me to forget that :3

Manipulating the reportId parameter’s value into 77d41ef9–1ebc-4d92–84e7-d5948e5940ed results in 500 Internal Server Error.

500 Internal Server Error

This shows this request got rejected by the server. Why?

Could the reason be 77d41ef9–1ebc-4d92–84e7-d5948e5940ed is an invalid report id value? After all, what I did was only change the first character of my original report id value from 8 into 7.

Let’s see what happens when I used a valid report id which is obtained from another Google account.

200 OK when changing the value into a valid report id

Through the above trials and errors, I can conclude that

500 Internal Server Error occurs when I used an invalid report id

403 Forbidden occurs when a user tries to perform unauthorized action, which should happen when I perform the actions, but in this case it didn’t

200 OK occurs when the unauthorized action is approved by the server

I then send up a following email to explain it.

Proof of concept video

Disclosure timeline

  • 22 Nov: Initial discovery and report
  • 23 Nov: Sent details about reportId parameter can be manipulated
  • 04 Dec: Followed up
  • 05 Dec: Report state changed into Not Reproducible
  • 05 Dec: Shared more information to Google security team
  • 09 Dec: Followed up
  • 14 Dec: Report is assigned with P2 priority
  • 15 Dec: Report state changed into Not Reproducible
  • 15 Dec: Shared another unlisted video to Google security team
  • 16 Dec: Report accepted as P1
  • 03 Jan: Followed up
  • 04 Jan: Bounty awarded
  • 04–22 Jan: Back and forth emails about how the bug is evaluated
  • 04–05 Feb: Confirmation of fix by Google security team

Takeaways and lessons

  • Always diving straight into hacking the application? Why not take some time to understand it? :3
  • Treat it like you’re playing a new game. Study and poke around, observe how it works and how it behaves when you tried something malicious.
  • Think like the defenders. If you noticed a repeating pattern that’s secure, try finding new patterns and pivot through there. Patterns can be identified through the same error response, same request parameters and so on.
  • When testing for IDOR, pay attention to the response pattern when it’s unsuccessful. That way, when you encounter a different response pattern, it might be a successful IDOR.
  • Take some time to jot down and think, what kind of actions you shouldn’t be able to perform but there’s a chance that developers isn’t aware of it?
  • When in doubt, ask yourself why your vulnerability is a valid vulnerability and what can you do with it?

That’s it for now, any claps are appreciated ;)

Follow me on Twitter!

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade