In today’s post, I will talk with 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 while having a little bit of fun.
I started to interact with the web application and follow 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 process input-data coming from the user. I started to look 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 for that moment I felt like I was stuck and as I didn’t have many 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:
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 may have spotted 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:
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:
If this parameter was set, a new <link> tag was 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 was a valid finding and also could have been exploited by an attacker.
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 may have a security bug and the most important thing is to stay creative and never give up your chance and motivation. I hope you enjoyed this post, see you soon!
Alexandru Coltuneac, LooseByte