Socially-Engineered XSS Attacks

When the IE team talks about Cross-Site-Scripting (XSS) attacks, we’ve usually grouped them into three categories

  • Type 0: DOM-based XSS
  • Type 1: “Reflected” XSS
  • Type 2: Persistent/Stored XSS

DOM-APIs like toStaticHTML enable pages to protect themselves against Type 0 attacks. The Internet Explorer XSS Filter can block Type 1 attacks by detecting reflected script and neutering it. Servers can protect themselves against Type 2 attacks using the Anti-XSS library to sanitize stored data.

It turns out, however, that there’s a fourth type of XSS attack: Socially-engineered XSS. In a socially-engineered XSS attack, the user is tricked into running an attacker’s JavaScript code in the context of the victim site. Even if a site follows best-practices to block XSS Types 0, 1 and 2, they may still be vulnerable to Socially Engineered XSS attacks.

Such attacks work in the same way as most socially-engineered attacks, by attacking the weakest link in browser security—the user’s trust. The attacks request that the user perform a series of operations (often using keyboard key combinations) that result in a JavaScript URL being entered in the address bar and invoked. JavaScript URIs entered in this way execute in the context of the currently loaded page. Users are tricked into following these instructions with the promise of some reward (e.g. free “points” for games, “secret” information about other users, etc).

Here’s a screenshot of an attack that I encountered yesterday:


Now, I’ve seen far slicker versions that mask themselves far more cleverly, such that the script isn’t ever seen. In the manner of an old game cheat, the unknowing user presses CTRL+C, CTRL+L, CTRL+V, ENTER, and the bad guy’s code runs.

These attacks often target popular social networks, and their first action upon running is to spread to all of the user’s contacts, leading to an extremely rapid infection across the social graph. Thousands of users can fall for an attack like this in a few hours. After arranging to spread to the user’s contacts, these attacks typically engage in spamming malware-distributing links or other activities that generate revenue for the bad guys. Because the script runs in the security context of the victim page, any information on the current site may be available for perusal by the attacker.

In Internet Explorer 9, we’ve added a simple protection that significantly raises the bar against this type of attack. Specifically, IE9 will remove the “JavaScript:” prefix[1] from any string that is pasted into the address bar. So, in order for a user to fall victim to a self-inflicted attack of this nature, they have to be persuaded to copy/paste the attack code in the address bar, then go to the beginning of the URL, type “javascript:” and hit enter. This additional step adds complexity (and suspicion), and our early data that indicates that IE9 users are much less likely to fall victim to such attacks.

Web-elites who would recognize this attack immediately (e.g. many readers of this blog’s small readership) might think this new protection cumbersome, since they can no longer trivially paste things like “javascript:alert(document.cookie);” into the address bar to see the current page’s cookies. However, IE will still allow pasting of the code itself, so you need only type the JavaScript protocol prefix. For script operations you undertake frequently, you can store the code in a simple Bookmarklet and simply invoke that rather than trying to paste in the address bar. Internet Explorer 9 includes several improvements for bookmarklets. In IE9, a bookmarklet may now contain up to 5kb of JavaScript (previously, the limit was 2083 characters), and bookmarklets may again be dragged from a webpage into the Favorites bar, triggering the following prompt:


-Eric Lawrence

[1] Internet Explorer will actually strip out any script-prefix, including misspelled strings that might otherwise be autocorrected into a script prefix. Also, if there's existing content in the address bar (e.g. a j) if adding pasted content (e.g. avascript) will create a script prefix, it will still be removed.