Top-Level Universal XSS
A flaw in Internet Explorer could expose users to JavaScript exploits and Universal XSS by abusing the way the browser classifies websites into specific security zones.
What is Universal XSS?
Generic Cross-Site Scripting (XSS) flaws only affect the original website that has the XSS vulnerability. For example, XSS in facebook.com grants an attacker access to the victim's Facebook session, but browser security prevents the flaw from affecting other websites.
Universal XSS (UXSS) is when it is the browser behavior that is exploited, and the standard controls that prevent other websites from being affected are ignored. UXSS is essentially creating an XSS flaw where there is none.
The Threat of Two Letter Websites
In February of 2012, I wrote about a group of websites that are being hosted at the root level of custom Top-Level Domains (TLD) such as http://io./ and http://ai./. At the time, I posed the question, “If there are XSS vulnerabilities on a Top-Level Domain, could it affect all of its subdomains?”
It turns out that XSS on website hosted at the root level can lead to very bad things much worse than I originally thought: Universal XSS; a single XSS vulnerability that can perform cross-site communication to any other domain. I'm going to explain the circumstances of this vulnerability and how it can be exploited.
I want to thank Pujun Li (@jackmasa) for bringing this to my attention and the Microsoft Security Response Center for quickly getting back to us on this issue.
The Intranet Zone
Internet Explorer maps out websites you visit into specific security zones: Internet, Local Intranet, Trusted Sites, and Restricted Sites.
The Local Intranet Zone is a zone designated for trusted content; content hosted on your local network by your confident network administrators. In this zone, security measures are reduced across the board, and sites mapped to this zone do not use IE’s built-in ActiveX or XSS filters. Same Origin/Cross-domain boundaries are reduced, and JavaScript is granted additional cross-domain functionality to communicate with external websites. Why? Presumably to prevent things from breaking in the corporate network. If an attacker can get a malicious JavaScript within the Intranet zone, he effectively controls the rest of the websites that the victim interacts with.
From Internet to Intranet
The problem is the Intranet Zone, which Microsoft’s Eric Law goes into great detail in his MSDN IEInternals blog post The Intranet Zone. Every website Internet Explorer visits goes through a sequence of checks to determine which security zone the page should load into. One of these checks is called:
The PlainhostName rule (aka “The Dot rule”):
If the URI’s hostname doesn’t contain any periods (e.g. http://team/) then it is mapped to the Local Intranet Zone.
A site hosted at the TLD doesn’t have any periods in the hostname, and so the Internet hosted site gets incorrectly classified as an Intranet hosted site.
Eric concludes the post saying “none of [the TLD] sites can be loaded from most corporate networks.” I don’t know about most corporate networks, but I feel it’s important to go over the various requirements that need to be met before the UXSS vulnerability can be exploited.
Enabling the Intranet Zone
When the Intranet Zone is enabled in IE, we are left with a website that is on the Internet, but loaded in the less-secure Local Intranet Zone.
A user in a managed enterprise network is likely to have the Intranet Zone enabled by default. For home users, the Intranet Zone has been disabled since the release of IE7, but that means that it is enabled for Internet Explorer version 6. Combined, that's actually a pretty huge attack surface.
While the Intranet Zone is disabled by default for home users, once it is enabled it stays that way for all future requests. So how do you enable the Intranet Zone?
The instant a website is accessed that Internet Explorer interprets as possibly being on the local network, there is a warning message:
Intranet settings are turned off by default. [Don't show this message again] [Turn on Intranet Settings]
Clicking “Turn on Intranet Settings” provides a secondary confirmation, “Are you sure you want to turn on intranet-level security settings?”
Intranet settings use a less secure level than the Internet. If you only go to Internet websites, you should not turn on intranet settings.
Are you sure you want to turn on intranet-level security settings?
Click YES and the Intranet Zone is permanently enabled and the page is reloaded.
Once again, this only needs to be done if the user has never enabled Intranet Settings in the past and is not on a managed network, but for everyone else it’s still a lot of steps to be tricked into following. Fortunately for the bad guys, these roadblocks can be overcome with a little social engineering and good timing. The victim only needs to tab over and select the "Turn on Intranet Settings" button, activate it, and then provide a Yes response to the confirmation dialog. So, the attacker creates a scenario where it would make sense to type a few keystrokes, then the specific key combination [TAB] [TAB] [ENTER] [Y].
Security Risk
In IE, every site on the Local Intranet has carte blanche access to sensitive data on the rest of the sites on the Internet. This includes the ability of JavaScript to run against unassociated domains, something that is normally disallowed by browser Same Origin Policy. There is one caveat though, and once again it comes in the form of a confirmation dialog:
This page is accessing information that is not under its control. This poses a security risk. Do you want to continue?
If the user clicks “Yes”, the JavaScript program gets unrestricted access across the rest of internet. How does that attacker get the victim to click “Yes”? Once again, they can use social engineering and timing. All the attacker has to do is get the victim to type the letter [Y] one more time to confirm YES at the prompt.
So, if you own a TLD and host a website at the root level, you can do some pretty mean things.
But what if you don’t have the $185,000 needed to register your own TLD from ICANN?
I suppose you’ll just have to rely on vulnerabile code in-use by somebody who has already paid the fees and set up a website. Perhaps you will find one running a CGI script with XSS Vulnerabilities. Cool, but what about IE's XSS filter, won't that stop the attack? After all, it is pretty good at detecting and preventing XSS, right? Unfortunately, the filter is completely disabled in the Intranet Zone, raising the threat and ease of exploiting XSS on TLD hosts.
Misdirection
I took this vulnerability to Microsoft to see what they thought of it. My understanding is that because of the numerous confirmation prompts and variables, they didn't see it as a very high threat. In theory I agree, and it's hard to see this as a typical drive-by exploit. However, I would like to point out one more thing that could make exploitation easier: The warning messages do not give any indication about which website IE is attempting to load in the Intranet Zone or access cross-domain content. It isn't obvious whether you are under attack, or if you simply visited a website that's attempting to take full advantage of the abundance of features that IE provides. Loading the TLD site in a hidden iframe means that the user does not receive any visual cues about which website is attacking them, or what information is being hacked.
Show me the money
I bet you would like to see a POC now, wouldn't you?
An attack of this nature isn’t just theoretical; it’s entirely possible. I discovered that one of the companies hosting websites on its root domain uses a CGI script that is vulnerable to XSS. Without considering the flood of new companies that will soon have their own TLD, there are at least four websites (tm, sh, io, and ac) that can be used right now by attackers as a jumping off point for this vulnerability and used steal sensitive data and bank account information, or hack into social networks and email accounts.
Here's a live proof of concept for IE9. The injected JavaScript in the URL creates a request that simply grabs the response headers of reddit.com including any new cookies and displays them in an alert as evidence that the Same Origin Policy has been ignored. Similar code can just as easily be written to grab CSRF tokens and submit new votes and posts under your Reddit username.
http://ac/cgi-bin/idn?data=%1N%1e%1cscript%1ex=new XMLHttpRequest;x.open('get','http://www.reddit.com');x.send();x.onreadystatechange=function(){if(x.readyState==4)alert(x.getAllResponseHeaders())};void(0);%1c%0fscript%1e
Update 1: To get a better idea of what the attack could look like, check out a video demonstration.