Found a Google XSS Vulnerability
Programmer Matan found an XSS vulnerability and reported it to Google, receiving a reward of $3,133.7 (approximately ¥22,666 RMB).
Here are Google Bug Hunter's reward rules:
Here's how it started. Matan read an article exposing a Google SSRF vulnerability that mentioned this Google website:
📍 https://toolbox.googleapps.com
So he began exploring, first by checking the robots.txt file:
#apps-toolbox
User-Agent: *
Allow: /apps/main
Allow: /apps/browserinfo
Allow: /apps/checkmx
Allow: /apps/dig
Allow: /apps/har_analyzer
Allow: /apps/loganalyzer
Allow: /apps/loggershark
Allow: /apps/messageheader
Allow: /apps/recovery
Allow: /apps/useragent
Allow: /apps/other_tools
Allow: /apps/encode_decode
Allow: /apps/screen_recorder
Disallow: *
robots.txt is a file at the website's root directory that tells web crawlers which pages can be crawled and which cannot, to avoid the website being overloaded with crawler requests.
In the robots.txt file, each link corresponds to a tool webpage.
But there's one exception: /apps/recovery
cannot be accessed directly.
After a simple search, he discovered it has subpages:
recovery/domain_in_use
recovery/form
recovery/ownership
These subpages can all accept multiple URL parameters, for example:
recovery/domain_in_use?visit_id=xxx&user=xxx&domain=xxx&email=xxx
If you enter this continue redirect link:
https://toolbox.googleapps.com/apps/recovery/ownership?domain=example.com&email=email@example.com&case=45500368&continue=/apps/recovery/...
This link contains the parameter domain=example.com
, and note there's also a continue=/apps/recovery/...
parameter.
Entering this continue redirect link gives a prompt:
Here's where the problem was discovered - the CONTINUE button's link actually comes from the continue
parameter!
Matan tested it by injecting JavaScript code: .../continue=javascript:alert(document.domain)
Successfully executed ✅
This website has no CSP security policy and no protective measures, so it can fetch resources from any external source.
He continued trying to load an external malicious script that retrieves the user's IP address:
.../continue=javascript:fetch(%27https://api.ipify.org?format=json%27).then(response=%3Eresponse.text()).then(data=%3E{alert(data);%20})
Also successfully executed ✅
At this point, the XSS vulnerability was confirmed.
Let's review XSS knowledge:
XSS (Cross-Site Scripting), cross-site scripting attack, occurs when validation is not properly done, trusting user input and accepting malicious input from attackers (usually JavaScript code), causing that malicious input to execute on other users' pages. XSS is generally divided into three types:
- Stored: Malicious input is permanently stored in the backend service. Whenever users open the website and retrieve that malicious input, the browser executes it.
- Reflected: Malicious input is embedded in URLs or other inputs and immediately forwarded by the backend. As long as users visit the crafted URL, the browser executes it.
- DOM-based: Attackers manipulate the user's DOM structure to execute malicious code.
Matan's example above is a typical reflected XSS.
But this XSS is so basic that even Matan himself found it hard to believe, especially since Google's technology is famously good in the industry.
However, Google habitually uses their own frameworks, and when these frameworks don't implement proper security policies, product failures are inevitable.