Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Facebook Lacked X-Frame-Options - How I Fixed It

DZone's Guide to

Facebook Lacked X-Frame-Options - How I Fixed It

Free Resource

Start coding today to experience the powerful engine that drives data application’s development, brought to you in partnership with Qlik.

In September 2011, I discovered a vulnerability that allowed an attacker to partially take control of a victim's Facebook account. Vulnerability allowed the attacker, among other things, to send status updates on behalf of user and send friend requests to attackers' controlled Facebook account. The vulnerability has been responsibly disclosed as part of Facebook Security Bug Bounty program and is now fixed.

Details

http[s]://www.facebook.com/plugins/serverfbml.php only used JavaScript for frame-busting and did not use X-Frame-Options header. It was possible to create a UI redressing content extraction attack to trick the user into dragging HTML source of that page into the attacker's page. This relied on Firefox's ability to display view-source: protocol pages in iframes AND the ability to perform drag & drop actions cross origin (So only Firefox users were affected).

The mentioned page rendered FBML specified in the $_GET parameter. In this case <form><fb:captcha></form> was used as an exemplary FBML payload. In the server response there was a Javascript Env object with multiple sensitive user values:

{
  user:100001652298988,
  locale:"en_US",
  method:"GET",
  start:(new Date()).getTime(),
  ps_limit:5,
  ps_ratio:4,
  svn_rev:441515,
  static_base:"https:\/\/s-static.ak.facebook.com\/",
  www_base:"http:\/\/www.facebook.com\/",
  rep_lag:2,
  post_form_id:"eecde0da0dc4bc800d385dde5dd37608",
  fb_dtsg:"AQAUh3Jx",
  lhsh:"0AQAQVvsl",
  error_uri:".....",
  retry_ajax_on_network_error:"1",
  ajaxpipe_enabled:"1",
  theater_ver:"2"
};

In the source above, apart from user ID (privacy!), there are also two interesting values: fb_dtsg and post_form_id. These values alone are a form of anti-CSRF token used in Facebook, and, by knowing them, the attacker could post status updates on behalf of a logged in user. In Firefox it was possible to trick the user to select & drag these values to attacker's controlled page.

So, if any user authenticated to Facebook navigated to attacker's URL (e.g. via a link shared by his friend) and played a game, the attacker got access to HTML source of a vulnerable Facebook page and came into possession of user id and CSRF tokens. Having that, he could perform multiple CSRF requests, using the fact that victim's browser had appropriate FB cookies.

Demo

In The demo I'm using is a modified version of double drag&drop UI redressing technique developed by  Nafeez Ahamed (@skeptic_fx). As an exploitation example, a status update for a victim user is posted, and a friend request is sent to another user (by a possible attacker). Of course, there are more possibilities with these tokens like sharing and liking a given URL, but I haven't researched that.

Some fixes are quick, others...

The proposed fix was: Use X-Frame-Options at the mentioned page. Vulnerability in Facebook has been fixed, tested and deployed before Oct 14, 2011. However, the relevant Firefox bug #605991 ( Drag-and-drop may be used to steal content across domains) waited 2 years and the fix has just been deployed in Firefox 14. As of Firefox 14 you can no longer drag&drop content cross-domain. So - update your Firefoxes and stay safe!

Create data driven applications in Qlik’s free and easy to use coding environment, brought to you in partnership with Qlik.

Topics:

Published at DZone with permission of Krzysztof Kotowicz , DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}