Stealing CSVs crossdomain

Back in 2008, Chris Evans found it was possible to steal data cross-domain in Firefox using script includes. We can still read his report at;
http://scary.beasts.org/security/CESA-2008-011.html

In his own words;

The modern web model permits remote domain <script> inclusion with no restrictions. If the remote data, which does not have to be script, has an effect on the evil domain doing the inclusion, you have a cross-domain data leak.

The idea was to use JavaScript error messages combined with 302 redirect. In general, modern browsers replace JavaScript error messages with a generic message like “Script error” to prevent leaking of error messages to remote domain. In case of same domain, detailed JavaScript error messages can be read.

I’ve found the same issue in IE 11 but with a peculiar prerequisite;
– The loading page (more precisely- Tab) must have its Developers Tools open (or previously opened)

Yes, it’s weird but it doesn’t work if Developers Tools is not open or previously opened. Few other prerequisites which are essential for script inclusion attacks are;
– The values must form valid JavaScript variable names
– The included data, as a whole, must form valid JavaScript code

The best error message to target is “blah is not defined”, referring to a textual name that is not currently bound to a variable. You can cross-domain steal data that is a single word in this manner. If the cross-domain data is CSV, e.g. “a, b, c”, you can steal the text of all three words by iteratively sourcing the script, noting the undefined variable name, defining it and repeating.

So, basically, we can steal contents of any CSV file as long as it meets above prerequisites. In fact, we can steal any type of data as long as it meets above prerequisites, not only CSVs. It is also possible to use different charsets to steal data as long as the included page doesn’t specify its own charset. This is shown in Gareth‘s post which I’ve added in REFERENCES.

Since, Chirs Evan’s POC is no longer live and doesn’t showcase stealing multiple values/variables, I’ve set up a POC which supplements his one at;
http://rootme.in/xssi?url=/redirect%3Furl%3Dhttp%3A%2f%2frequest.rootme.in%2ftoken.csv

You can also play with it, supplying your own arguments like;
http://rootme.in/xssi?url=http://example.com/user_info.js&eval=alert(email)

Here’s a 15 seconds video I made for POC;

I reported it to Microsoft but since it requires Developer Tools be opened or had it opened, it was not considered for fix atm. However, as they said, it may be resolved in future version update.

There is another, still working, POC that Gareth found which works perfectly in MS Edge. If you’re interested, you can read about it at;
http://blog.portswigger.net/2016/11/json-hijacking-for-modern-web.html

To remediate the issue, developers or website owners can do one or any combination of;
– Switch to POST method
– Use secret tokens as in CSRF Protection
– Make URL unpredictable
– Strict referer checking

If the data is supposed to be retrieved via ajax requests for further processing, one can also;
– Use Parser-Breaking syntax like for(;;)
– Use custom HTTP header

Also, specifying correct Content-Type header and X-Content-Type-Options: nosniff would suffice to remediate the issue for this particular case. However, I wouldn’t consider it a strong fix as there are browsers which still don’t support X-Content-Type-Options.

 

Thanks
Special thanks to @albinowax for his feedback and thorough proof-reading.

 

REFERENCES:
http://scary.beasts.org/security/CESA-2008-011.html
http://balpha.de/2013/02/plain-text-considered-harmful-a-cross-domain-exploit/
http://www.mbsd.jp/Whitepaper/xssi.pdf
http://blog.portswigger.net/2016/11/json-hijacking-for-modern-web.html