Some days ago my friend Gareth Heyes exposed an authorization bug in Twitter’s JSON interface, by writing a short post titled I Know What Your Friends Did Last Summer. Do not click on his PoC with JavaScript enabled, unless you want to find yourself bombed by a lot of alert boxes showing some interesting Twitter data about you and your friends.

For your convenience, I’ve reproduced a less annoying PoC here:

Are you logged in Twitter?

Notice/update: after some hours this article was out, Twitter secured its “friends timeline” feed. Therefore I updated this PoC to consume the “public” feed, still demonstrating the hijacking technique, albeit on a non-sensitive data set.


Twitter’s JSON feed is spied upon using __defineSetter__, a useful JavaScript extension introduced by Mozilla and now implemented in all the modern browsers (i.e. all the popular ones except IE). After redefining a property setter on Object.prototype, we can read the values being set when the feed is loaded through a <SCRIPT> element:

Object.prototype.__defineSetter__("user",
  function(value) { // do something with user's value }
);
<script src="https://twitter.com/statuses/friends_timeline/"></script>

The main problem here is, obviously, Twitter leaving this feed unsecured against cross-site requests, under the wrong assumption that it could be read only through XMLHttpRequest (which actually does not work cross-site). We can expect errors like this to be quite widespread, since so-called “AJAX security” is still in its infancy: consider that Twitter guys are not exactly newbies…

This JSON-hijacking technique won’t work if any of the following conditions applies:

  • The feed provider (Twitter) secures its JSON to ensure 3rd party sites can’t access it (i.e. implementing any anti-CSRF countermeasure).
  • The JSON payload is not enclosed in square brackets. If the JSON starts directly with curly braces, it gets intepreted as a code block, rather than an object initializer, and nothing happens.
  • You’re using an antiquated browser (like IE).
  • JavaScript execution is disabled on the attacker’s site (e.g. by using NoScript in its default configuration).
  • You’re preventing 3rd party scripts from loading (e.g. by using Adblock Plus with its rather inconvenient 3rd party script blocking feature enabled). Forget it, too much easy to work-around :(
  • You’re using NoScript 1.8.8.95 or above, even if you’re allowing scripts everywhere!

Yes, that’s right: in the best NoScript tradition, while there’s some ongoing work to prevent this kind of leakage from happening in next major version of Firefox, NoScript already provides a specific protection feature. Even better, this works even in Allow Scripts Globally mode, just like anti-XSS filters and the ClearClick anti-clickjacking technology, so you’ve got no excuse to stay unsafe.

P.S.:
another thing you can do for your Twitter security, especially if you use public wifi, is adding twitter.com to your HTTPS behavior forced list and enabling automatic secure cookies management, to defeat cookie hijacking attacks.

Update

Twitter fixed this issue by requiring HTTP authentication in order to retrieve the https://twitter.com/statuses/friends_timeline.json feed.
I’ll post a new innocuous didactic PoC fetching the public feed and circumventing Adblock Plus as soon as I’m done with breakfast.

22 Responses to “You Don’t Know What My Twitter Leaks”

  1. #1 Aerik says:

    I think you can lay off on the third-party blocking feature now, Giorgio, because as of yesterday, adblock plus users can create filters that only apply on what domains they want. For example,

    *$script,third-party,domain=|blogspot.com|twitter.com|~hackademix.net

  2. #2 Gareth Heyes says:

    Hey Giorgio how about a url blocker in noscript? You could then selectively choose to block vulnerable pages. I’d prefer a whitelist blocker but I’m not sure it would be usable. I could think of a few vulnerable urls I could block.

  3. #3 Giorgio says:

    @Aerik:
    I’m not convinced yet it is as usable as NoScript.
    You still need to know how to write a filter, right?

    @Gareth:
    I’m not sure it’s a great idea (you’re better off with a local proxy, I guess).
    However you’ll be surely able to configure ABE for that.

  4. #4 Aerik says:

    Is writing adblock plus filters supposed to be hard or something?

  5. #5 Giorgio says:

    @Aerik:
    writing a filter is not hard at all, but it’s surely more time consuming than clicking “Allow somesite.com” or, like in this case, doing absolutely nothing (if you’re in “Allow globally mode”) :)

  6. #6 Aerik says:

    I still think your criticisms of Adblock Plus in this area are lacking. When you allow a third-party site in noscript, you allow every javascript file from that domain or subdomain you chose. Whereas instead you could allow specific files with adblock plus. Again, this is the kind of thing where the ideal is using both extensions together.

  7. #7 arimfe says:

    #1
    Having both "twitter.com" and "~hackademix.net" in the same filter is meaningless unless they are related as subdomain. Better to keep the whole filter strictly whitelist based "*$script,third-party" and complement with site-restricted allowance "@@twitter.com$domain=hackademix.net".

    I agree with Aerik here. The most valuable feature for Adblock is site-restricted allowance. If a site has forced the Noscript user to allow just one single 3rd party server, the user is forced to allow that same server as 3rd party for all his trusted sites…
    Adblock is a bit ahead in the game of 3rd party control here.

  8. #8 Giorgio says:

    @Aerik, arimfe:
    NoScript’s key concept is site trust. If you trust a script source, you trust it either if it’s first party or 3rd party. Other security benefits of blocking 3rd party scripts are obtained with XSS countermeasures and other specific features. If you really need to load a script from a source you don’t trust, you’re safer using NoScript’s Temporarily allow command than setting a permanent AdBlock Plus whitelist filter.

    Aerik knows well that I often advocate Adblock Plus usage together with NoScript in all those circumstances when you deem convenient to selectively block certain annoying files coming from domains you basically trust, security wise.

    But if you’re handling sites you do not trust, you can’t rely on AdBlock Plus, and the reason is simple and understandable: AdBlock Plus can be easily worked-around in several ways. More in general, AdBlock Plus and FlashBlock, despite a common misconception, can’t be regarded as security tools because they’re not conceived nor developed with the necessary defensive and proactive paranoid mindset. They do a fantastic work as annoyance blockers, but you can’t trust them for your security.

    I just updated this post and the PoC to reflect both the Twitter’s fix and AdBlock Plus’ inadequacy to preemptively block this kind of attack. I apologize for my original write-up misleadingly suggesting that it might help.

  9. #9 Gareth Heyes says:

    The adblock plus point is a good one, you don’t even need to write a filter because the content is listed anyway. Makes it nice and easy to block certain items. The only thing it lacks is a way to block pages but you can do that with a custom filter as stated,

  10. #10 Giorgio says:

    @Gareth:
    you obviously missed by previous comment (race condition?) :)

  11. #11 hackademix.net » Twitter JSON Hijacking Updates says:

    […] You Don’t Know What My Twitter Leaks 13 01 2009 […]

  12. #12 Gareth Heyes says:

    @Giorgio

    Ah ok you raise a good point there, my interest was to block certain sites vulnerable pages to protect against CSRF. I guess a local proxy like Proxomitron would be the best solution although not as nice as adblock’s functionality.

  13. #13 Giorgio says:

    @Gareth:
    As I told you, the ultimate client-side protection against CSRF will be ABE.

  14. #14 Gareth Heyes says:

    @Giorgio

    Cool I like this feature:-
    Site www.somesite.com/logout
    Accept GET, POST from SELF
    Deny

    When is it ready? Also is there gonna be a UI for the rules creation?

  15. #15 Giorgio says:

    @Gareth:
    ABE should be ready for general consumption by June (there’s even a formal project plan), but I should have something testable by the end of February, unless a more important release interferes too much.

  16. #16 Gareth Heyes says:

    @Giorgio

    maone-20rc1 takes priority :)
    Congrats btw!

  17. #17 links for 2009-01-13 | Yostivanich.com says:

    […] hackademix.net » You Don’t Know What My Twitter Leaks Another Twitter security hole. (tags: twitter security programming webdevelopment) […]

  18. #18 Woot! What’s Buzzing Now? » Blog Archive » This is What I’M Looking At Today. « Shades’ Trades & More says:

    […] hackademix.net » You Don’t Know What My Twitter Leaks […]

  19. #19 wawadave says:

    though you say writing a filter is easy i do not know how as i,m sure many do not.
    Plus there is allso the need to know what sites would have to be added again i do not know. So others will not ether.

  20. #20 Firefox Add-On NoScript Updated to Version 1.9.0.6 | Infosecurity.US says:

    […] New exclusive protection against JSON and E4X hijacking. […]

  21. #21 JSON Hijacking | Test Blog says:

    […] However, there’s another related exploit that seems to affect many more browsers. It was brought to my attention recently by someone at Microsoft and Scott Hanselman and I demonstrated it at the Norwegian Developers Conference last week, though it has been demonstrated against Twitter in the past. […]

  22. #22 JSONP (yIII): Cuestiones de seguridad y ASP.NET rompiendo la compatibilidad en 3.5 - Blog de José Manuel Alarcón Aguín en Geeks.ms (alternativo a www.JASoft.org) - Geeks•ms says:

    […] utilizar (muchas de las cuales ni siquiera son conocidas hoy, pero pueden surgir). Por ejemplo, Twitter fue crackeado no hace mucho usando técnicas avanzadas de JavaScript y el acceso a los datos JSON remotos […]

Bad Behavior has blocked 36036 access attempts in the last 7 days.