I just wrote a proof-of-concept worm that steals session cookies. It spreads by retweeting. If something like this was released it would spread like wildfire.
Reminds me of the MySpace worm that took the site down
Time to change your passwords!
(Edit: I will post the vuln code once this is patched. Atm I am playing with having the payload make Ajax queries back to Twitter :). Having shortcut functions in the page (ie. $() to grab an element), url shorteners and ability to include external JS mean that you can do almost anything in the 140 char payload.
Explainer:
The vulnerability is because URL's are not being escaped properly. For eg. the following URL is posted to Twitter:
You can see that by putting in the URL and the trailing slash, Twitter thinks it has a valid URL even though it contains a quote mark in it which allows it to escape the URL attribute and include a mouse over. You can write anything to the page, including closing the link and including a script element.
You don't have to use onmouseover. You could close the link and then insert some external javascript that can re-write your tweet to make it look innocent (or hide that entire tweet), then attach a mousemove event to the body document. This means you could propagate a worm silently and without requiring a mouseover on the actual tweet.
(edit: pretty concerned about the number of people here who think that being able to inject javascript on a site in the context of a users session is not a big deal)
What is the significance of the "@"? Is it because once they encounter the @, they split into a different parsing routine (for example to link @replies)?
If you look at the regex they were using, once it sees an @, it then scans forward until it encounters a /, which is what let's you sneak in anything after the @ other than a /.
Is it really necessary to change one's password? I've logged out and logged in again to make sure I invalidated my old session cookie. Hopefully that's sufficient.
Depends on whether Twitter stores plain text passwords and allows sign in users to see them. Also, it is more importanttto revoke oauth tokens than change passwords because last time I checked the oauth tokens are still valid even if You change your password.
It's caused by Twitter's insufficient escaping of URLs, specifically a rogue quotation mark character can be injected after the @ symbol and thus you end up with something like <a href="URL@" onmouseover="insert XSS attack here">...</a>
So this attack won't work on other sites that escape URLs properly.
It is made a little harder since you cannot use # or @ in the tweet, and your exploit code is limited to ~130 characters, but if you use $.getScript(), oh boy...
Who here didn't, at least for fun, try to make his own version of the Javascript bit? I'd like to have a variant of the full black Quine that randomizes the color used. It would be so shiny and Twitter wouldn't prevent it from reposting.
Maybe I'm doing something wrong but it doesn't work for me. All I see is the code you pasted including the jQuery code. At least for me the flaw seems to be fixed.
That's still the wrong approach (if it's the only part of the solution) and I wouldn't be surprised that there's still a problem in there somewhere. That's the entirely wrong place to deal with this. The correct solution is the moral equivalent of "<a href='" + html_escape(url) + "'>", where "html_escape" converts the URL into a properly encoded HTML string regardless of contents, and for simplicitly I'm assuming some other cleansing process has run on the url elsewhere (to ensure http: or https: is the only legal beginning, etc). (This is the way you ensure you don't get XSS in your link. Other security properties that you may desire, such as controlling what the user can link to, get enforced elsewhere.)
Then it simply doesn't matter what the user has managed to get down to the link generation code, the html_escape code should at least ensure that the user is stuck in the link itself. There are some paranoia things such a function should still do, such as remove all characters that are not legal in links or removing all invalid characters (incorrect UTF-8, for instance), consult the relevant standards standard for a full description. But this is still way easier and therefore more likely to correctly avoid XSS than trying to pick up all possible badness at the parse step.
It continues to astonish me how hard people make this and how much developers resist being told that their code is problematic, and how surprised they are when their site gets taken down by the stupidest errors....
Also, if at all possible, I strongly endorse environments where you don't literally type "<a href='" + html_escape(url) + "'>", because you will forget the html_escape. There are a variety of ways to reach this goal, depending on language.
I don't understand what they are doing? I don't recall @ having special significance in a URL?
I can only guess that they have two separate steps for transforming URLs into links and transforming @replies into links. Then they first run the URL transformer and then the @replies transformer, which would of course mess up the URL.
I have solved that problem in one of my Twitter apps (transforming both in one go), maybe I should send them a code snippet...
They are trying to match URLs so that they can turn them into links. The @ character is valid in a URL. What I don't understand is why they don't URL encode the matching text.
As Rule #5 of your own link states: "WARNING: Do not encode complete or relative URL's with URL encoding! URL's should be encoded based on the context of display like any other piece of data. For example, user driven URL's in HREF links should be attribute encoded."
URL encoding is for querystring parameters. The HTML escaping is for the inside of attributes. You need to do both, in the proper place; I assumed you already had a URL with the proper escaping at the time that I was discussing, again, for simplicity, because the full story doesn't really fit in an HN comment: http://www.jerf.org/iri/post/2548
That's also why I mention you need a separate phase specially for URLs, where you will for instance immediately reject any URL that does not start with one of your whitelisted protocols, which "javascript:" won't be on. "javascript:" is far from the only protocol that can get you in trouble, it's just the most obvious.
As far as XSS vulnerabilities goes, this one is the size of the Gulf of Mexico. How exactly did they manage to let this one through? (Even more puzzling, it looks like this is special link-parsing functionality that someone had to actually write explicitly to make it work)
I wouldn't be terribly surprised, based on the timeline of exploits I've seen, if the wider abuse of this is due to the incredibly stupid exploit demonstration at the launch of @RainbowTwtr.
My related tweets from earlier tonight... ah, about the RainbowTwtr angle, not exploited tweets! :-)
Why is it stupid to tell people how insecure their favorite messaging platform is? So when they get hacked, they will have to wonder why? Sounds like a great plan...
If by "tell" you do not mean a cynical public reveal for the sake of product promotion and by "people" you mean the organisation running the platform (Twitter), I'd agree with you. :-)
No, it's just why developers should HTML-escape all user-contributed content before displaying it.
Building it into the templating engine just punishes all the devs who know what they're doing. Look at the history of things like MAGIC_QUOTES_RUNTIME to see what happens if you go down that route.
Clearly relying on developers to remember to escape didn't work (it's not first XSS and not last).
I don't think it's anything like magic quotes. It's more like prepared statements.
Magic quotes was enormous failure because it worked on input rather than output. In HTML-specific output code having HTML-escaping is just fine.
Lack of escaping enables worms and error isn't immediately visible. Double escaping is quickly visible, and it's harmless, which is why I think not trusting variables in HTML is a better default.
As soon as you start auto-escaping everything, you need to introduce a dontEscapeThis() method that you can use to actually render the HTML you intended.
Having to do that would be enough to make me ditch any framework in favor of one that treats me like a grownup.
What you need is a type system. All data that comes from the user is of type UnescapedUserString. When the templating system sees this, it escapes it when written as HTML. Strings that you type into your program that you don't want to be escaped are of type EscapedString. Add some concatenation rules, and you're done.
If you were using Haskell, you wouldn't even need to change much code to do this, thanks to overloaded strings.
Yes, lets needlessly make something harder and less secure in 99% of the cases because people want to be treated like a "grownup".
How many times have you written code that actually required raw, dynamic, unescaped html output in a template engine? I think I have... 2 times? And for 2 times I still had to escape the output 50% of the time - when displaying it in a form for the user to edit.
Ok, sorry if this question seems amateurish, but I don't quite understand this exploit. I went to my twitter page and it automatically posted a tweet, tried to send DMs etc. A lot of weird stuff was going on so I closed the tab immediately and looked for information on this.
Does it mean my account is somehow affected or is it just someone in my timeline who posted this exploit?
Edit: Maybe 'affected' is the wrong term. After reading the article again, I think this code just has to be in my timeline to work. Please correct me if I'm wrong.
download any non-web client (i suppose even mobile one will work, but non-javascript one), and remove all the messages that were posted by that script.
use non-web clients for reading and posting tweets for next day or two.
to be on a safe side, avoid using web version of client for several days, at least until it all gets figured out by twitter guys.
I got the Quine which changes the color and background color of the post to black. I initially though it was some sort of art. I admit I'm totally disappointed.
It's not a huge security flaw, just some (this time) harmless javascript injection. What it does is it fires a mouseover event, then fills the main textarea with itself and clicks submit.
It's clearly a huge security flaw, but as you say -- only within the context of twitter. Looking at the big picture of my life something like this doesn't even register. What's the worst thing that could happen, really? A popup? Maybe my account gets stolen somehow? Some garbage tweets in my timeline that I delete later with a non-web client? All of the sudden I'm following some spammers... I'd get over it.
You could send a DM to everyone you know with an shortened URL that links to a page full of malware and evil that pwns their computer, steals all their data and account log ins, and uses their machine as part of a botnet.
Because the DM would come from you, a person they know, the person is more likely to trust the page or file that's linked to and less likely to catch it brutalising their computer.
The actual data on your Twitter account might not be valuable in itself, but it has significant value as a vector for other attacks.
I just ran into this and it's amazing. The one I caught was an onmouseover that automatically propagates itself. Perhaps the world's first Javascript virus.
Relatively harmless as viruses go, so I have to admit to being a bit excited at watching a little bit of internet history unfold.
EDIT: mea culpa, you're quite right -- the potential for this is disastrous in terms of CSRF attacks and so on. I was thinking about this particular implementation that appeared to simply be propagating itself.
not harmless at all? this can do so much damage because you can run javascript in the context of the users session. some ideas for payloads:
* login as that user by sending yourself their session token
* scrape email addresses
* follow a spam account
* popup an affiliate site
* trigger a download or one of the new flash exploits to gain access to the local system
your code has to fit within 140 chars, but you can use the libraries that Twitter has included in the page (like $()) to grab elements and make Ajax calls to their backend.
tying things to specific IP address isn't a good idea. Some ISPs rotate outbound IP addresses on a per-connection basis. As in, when you refresh, you might be coming from a different IP. I think AOL first did this some years ago. It's a real shame.
My Twitter page has a frikkin overlay on it now, preventing its use. I define harm as not being able to use Twitter due to a malicious act. Sure, I haven't lost a leg, but it's a PITA. I'll probably have to change my password yet again too.
Reminds me of the MySpace worm that took the site down
Time to change your passwords!
(Edit: I will post the vuln code once this is patched. Atm I am playing with having the payload make Ajax queries back to Twitter :). Having shortcut functions in the page (ie. $() to grab an element), url shorteners and ability to include external JS mean that you can do almost anything in the 140 char payload.
Explainer:
The vulnerability is because URL's are not being escaped properly. For eg. the following URL is posted to Twitter:
Twitter treats this as the URL. When it is parsed Twitter wraps a link around that code, so the HTML now looks like: You can see that by putting in the URL and the trailing slash, Twitter thinks it has a valid URL even though it contains a quote mark in it which allows it to escape the URL attribute and include a mouse over. You can write anything to the page, including closing the link and including a script element.You don't have to use onmouseover. You could close the link and then insert some external javascript that can re-write your tweet to make it look innocent (or hide that entire tweet), then attach a mousemove event to the body document. This means you could propagate a worm silently and without requiring a mouseover on the actual tweet.
(edit: pretty concerned about the number of people here who think that being able to inject javascript on a site in the context of a users session is not a big deal)