In today’s post, I will talk to you about an interesting security vulnerability that I’ve found while I was working for one of my Google Grants. In case you don’t know, Google Grants is a program that complements the Google Vulnerability Reward Program (VRP) where bug-hunters receive different grants(rewards) for researching(testing) Google products.
About Google Cloud Blog
As the name suggests, Google Cloud Blog is the platform used by Google for presenting newly launched features and announcements for the Google Cloud Platform (GCP), a very cool suite of cloud computing services. One day, I was announced that I’ve got a grant for this blog platform and I thought it was a good opportunity for me to improve my skills.
I started to interact with the web application. I followed my usual reconnaissance steps while also trying to understand which are the main features of the web application and how does it process the data which comes from the end-user. After crawling and inspecting the existent web pages, I realized that the application was designed more like a read-only website rather than one which processes input-data coming from the user.
I also looked for implemented functionalities, but I couldn’t find anything else accessible except the Search feature. Bruteforcing existent files and folders didn’t give any useful result, and at that moment I was stuck and out of ideas.
Breaking the ice
As the number of lines of code was about ~29k, it wasn’t very efficient to take every line one by one, so I started to look for variables and functions which may be responsible for handling user-input data like “query”, “queryParams”, “URL” etc. This was the way I found the following line:
What this function did was to construct a URL (variable t) and load JSON pre-formatted code from that link. That code was then parsed and the whole page changed, as it was configured in the JSON file retrieved. From what I understood, this functionality was used by the Google engineers to see a live preview on the production GoogleCloud Blog website of the code changes they made internally.
The other possibility was that the functionality was introduced initially when the application was developed and tested internally and then it was overlooked when the web application was pushed to production.
The resource link was constructed from the input data coming from the user and it was formed by 3 parts:
- The constant value r.a.AUTHOR_URL which was already defined in the code as a link which pointed to one of google internal subdomains (https://gweb-cloudblog-author.googleplex.com)
- The value passed as parameter e (the previewUrl parameter passed earlier), which should have been in the form of a path (/folder1/folder2/folder3/)
- One query parameter called mode
The expected final URL would have been in the following form:
As you might have seen until now, there was no check in the code to verify if the path appended to the googleplex.com subdomain began indeed with a slash (“/”). An attacker could have supplied a value like “.1337hackz.com/” and in consequence, initiate a GET request to the following URL:
As a result, the JSON code was loaded from the attacker’s controlled website, who could then alter the content a legit article in almost any way he wanted (he could, for example, modify titles, images or body content).
HTML Content Injection to XSS
I was ready to create a new report and inform Google about this finding when I decided to take one last shot and see if there isn’t any way to escalate this vulnerability to a reflected XSS. This is how I got to the following lines of code:
The first conditional statement checked if the JSON file hosted and retrieved from the link constructed earlier has a seo_tag parameter. Just to have an idea, this is how the attacker’s hosted JSON file should have looked:
If this parameter was set, a new <link> tag was then dynamically created by the updateSeoLink function and appended to the webpage HTML content. This new tag would have had all the attributes specified by the attacker in the seo_tag parameter’s configuration, but the most important ones were the href and rel.
In the case of an HTML <link> tag, if the rel attribute is set to import then the resource pointed by the href attribute will be included in the current HTML document. Therefore, if the attacker set the rel attribute and pointed the href one to a maliciously hosted HTML content, then it would have been possible to insert valid HTML content into the webpage.
However, the CSP header blocked any attempt to load this kind of resource. Nevertheless, I decided to pack up all these details and sent them to Google since from my point of view this was a valid finding which could have been exploited by an attacker.
With this vulnerability, an attacker could have tricked victims into doing a set of illegitimate actions, by modifying the content of a web page belonging to the Google Cloud Blog. He could have created a malicious link and sent it to his victims over the internet, social media platforms, messages, etc.
Google Security Team accepted this vulnerability and fixed it very fast, as always. Surprisingly, they treated this bug as an XSS and rewarded it accordingly to the VRP rules.
For me, this story demonstrates once again that even if an application might seem secure at first sight, it might have a security bug. The most important thing is to stay creative and never lose your motivation.
I hope you enjoyed this post. See you soon!