First of all, here are some figures on Facebook : 500 million active members all around the world, including 50% connecting at least once a day, 60 millions updated status per day, 3 billions online photos, 70 available languages, more than 500 000 applications... Such figures could easily create envy, and many malicious minds have well understood the amazing potential of this social network. We can observe two main categories amongst these latter : those who exploit human flaws by tricking and luring people (especially through phishing attempts), and those who exploit the security flaws of the social network. Facebook has been quite exposed to security issues during the past three years, and the numerous applied security patches are there to confirm this fact. However, now that Facebook has become the second most visited site worldwide, we can wonder if its users can browse the social network safely and securely. This is actually the question we had in mind when we decided to perform a quick security audit of Facebook this summer. Auditing such a huge social network is not an easy task, and we focused on the basic essentials, which has been well sufficient. Here are the details of our findings.
Cross-site request forgery (abbreviated as CSRF) is a type of attack which an attacker tricks a user’s browser into performing undesired requests to websites where the user is logged in. Such attacks mostly use img or iframe tags pointing to scripts performing some actions for the benefits of the attacker. This type of attack is quite unrecognized, and many sites or web applications still provide no countermeasure.
On the other hand, XSS-type attacks (abbreviated as XSS) are well more widespread. During such an attack, the attacker succeeds in injecting a malicious script into a page read by the victim. This type of flaw is usually found in web pages where part of the content supplied to the user is generated from the user input itself. For a long time, this flaw has only been used to steal identification cookies from the users in order to hijack their session. But as we will see it, the emergence of social networks has given a fresh impulse to XSS flaws. If you are not familiar with CSRF and/or XSS flaws, these basics are illustrated in the two videos below.
There is several methods for websites to protect themselves against CSRF and XSS attacks. Regarding the CSRF flaws, a growing number of websites are now using a system of anti-CSRF tokens that accompany most of the users requests. These tokens are user-specific and are generally impossible to guess. They are thus used to verify the source and the legitimacy of the requests, just by checking if the tokens are part of the request or not. Facebook comes with such an anti-CSRF system, based on two tokens respectively called post_form_id (32 hexadecimal characters) and fb_dtsg (5 characters chosen from [a-zA-Z0-9.-]).
As far as XSS attacks are concerned, there is no universal countermeasure. The most efficient one is the use of the HttpOnly tag on identification cookies, which prevents these cookies from being stolen. However, an XSS attack can be far more complex than a simple cookie theft, as will be demonstrated in the last part.
Let’s start with the CSRF flaws. Actually, the first flaw is not a classical CSRF flaw, but it can be considered as such since it allows to retrieve the post_form_id token of any user, logged-in or not. This flaw (or rather bug?) can be found at two different locations:
http://www.facebook.com/ajax/stream/profile.php?__a=1&profile_id=<user_id>&viewer_id=<victim_id>The first script simply displays the wall of the logged-in user, but provides an additional functionality when the viewas parameter is included. Indeed, when this parameter is followed by the id of a lambda user, it allows to see how your own profile appears to this specific user. Unfortunately, this wonderful functionality has an annoying bug : when the logged-in user has allowed - through his security settings - anyone to comment on his wall, then the post_form_id of the lambda user is given back as a gift in the source code. We point out that this very functionality has already suffered from several vulnerabilities over the past year. As far as the second script is concerned, the mechanism is almost the same : this script provides a news feed on the profile of the user corresponding to profile_id, when viewed by viewer_id. All you have to do is fill the profile_id parameter with the id of the logged-in user, and the viewer_id parameter with the id of a specific victim : the post_form_id token of this latter will then appear in the source code, as long as the victim is allowed to comment of the wall of the logged-in user. This is quite interesting but what about the second token fb_dtsg? Unfortunately (or fortunately?), it is not possible to retrieve this token using the same technique. However, we will see that we can sometimes do without this second token...
http://touch.facebook.com/l_warn.php?u=<external adress>These scripts are used to redirect users towards external links, and they are generally called with two main parameters : the parameter u containing the external URL, and the parameter h containing a hash for source verification. When this hash is omitted, the user is warned that he is leaving Facebook for the given external URL. And yet this URL is not properly sanitized before being sent back to the user. Thus, the two following proof-of-concept URLs:
At first sight, these flaws can be considered as tiny flaws. However, it would be a big mistake to underestimate their potential. This is how we have decided to show in the two videos below, where we have built two scenarios in which an attacker succeeds in creating a genuine worm which takes advantage of the previous vulnerabilities to spread and cause major damages to the victim’s account. The first scenario is based on the CSRF flaws, and shows how all the victim’s personal information can be silently retrieved. The second scenario is based on the XSS flaws, and shows how the attacker can modify the access to the victim’s account, retrieve all the victim’s personal data, and finally destroy all of them. It is worth pointing out that in both scenarios, the spreading is ensured via messages sent to the victim’s friends and posts published to the victim’s wall, in which a Facebook application controlled by the attacker (see below) is highly recommended by the victim. We can thus reasonably assume that each victim compromises at least half of his/her friends, making the spreading of the worm exponential... and the gathering of personal data too.
In both scenarios, the attacker takes advantage of a very convenient possibility offered by Facebook, i.e. create his own application. It is convenient because it is available to any user, but is is also convenient because of the way it works. Indeed, when a user visits the canvas page of a Facebook application (http://apps.facebook.com/wargan_app for example), the URL pointing to the real location of the application - on an external server - is loaded in an iframe. This obviously allows an attacker to load any malicious external page in the user’s browser, using an official Facebook URL. This process is totally transparent for the victim, and he/she has no reason to be suspicious, thus making the attacker potentially very powerful. Now let’s watch the videos :
These videos clearly show how supposedly tiny flaws such as CSRF and XSS flaws, can be extremely dangerous when used over wide social networks. The scenarios which have been presented correspond to quite basic attacks, and it would be possible to elaborate far more complex scenarios, aiming for example at creating an army of zombie browsers or social botnet. All of this could even be combined with fashionable applicative flaws (PDF/Flash), and a simple XSS flaw could then lead to the compromising of millions of personal computers.
These vulnerabilities have been discovered by John Jean for Wargan Solutions.
Special thanks to Alex Rice (Facebook Security Team) for his kindness and responsiveness.
Contacter John JEAN (john at wargan dot com) -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.4.9 (GNU/Linux) mQGiBEo1REYRBADDGgkQVv+iN+LzRFH3WiDX+S0iTPg60MzTifYpfbeKH+FwdN/J /lujfR3TjielPEWVbYCnPJA/wHNNUACm6+qWoPx5SzjKq1BXMoGoUkO5DtXivboG NugVyKOBh7OARWilOkP6eB2zqbf/2ReHQtbX8a7xWyHzApyIAo/F2CiYOwCg7SyD UQifs08r8Um3pmyLMxTVjncD/1BrpfSWgYJYFLPobHuRvtoEyhK9ONuNWgQKYHQm mpoM6nxNVijySPpgyuyeDcyxgOzLJ3QI9Mqx+tmr1uLFZhAWSe0K5uz64pQ9PUMF LTvN5uN3sVAER4kA1Jxs5foTIkrCA6eQqmypIfo/egX1W1Y/1uC0aB0/kG11rQO0 fgUwA/4qubdS0PcnPZUQYVJUe6rDx5r2U/WVD+sHFY+ILFnVzdrxEdr1md35e9P5 ovuMfUunIwKH8BjSG3fXXESTZuZXfFlqwrR+m1y5qUcXwr9wnffRP2iQxIaQi5+b D4dR1J+oiNlPlVL8FuKK1dKHjIN9u4tjlE/VWCxoUyo97320z7QtSm9obiBKRUFO IChHZWVrIFdvcmthaG9saWMpIDxKb2huQHdhcmdhbi5jb20+iGAEExECACAFAko1 REYCGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAKCRBthXHBmOb+lvYJAJ9k30a7 lZx92PXQfNeoKocX5Uo3vACgtWuhqkDB1IvRMjMe49ng18Sp87y5Ag0ESjVERhAI AM0fzE0z5enz37lGPPHZrgW+XYWHNLfoR0gJvpu0FkPj4udPYL6+RJLGocWeJQBb UuEgcFdKJugxs3U9y/5iSFfM3e5+jOqPZCj6loP8nY9yarfVQHlZKqn6zseCT3D8 d1uTNJWnzb5LYnbFrETCyJbaENH8jzNQCGP3NCyIfXfn5Wag7HUh6Zi6njwl/2zx saizuQ3Wv0PjiVuJ8QEPvOdN9crTwt/JB2xRd98st7S5oEHvP96MyOtWSUWEnLSG fQhVyZC+aLLCOp8ggNkCAwOUGvPetJXVOLaPUJAoEwzDxXl43+GlKreqXH+W2GZT 0/n8W4p28Xrqv2G/SJa9sg8AAwUH/0GvW9eYRLaRDuAaBdlGX8jXsCnOvdMoioeg Wq9HwIYr94/kW2wJ1QFnhuEU/0cwx9MVrMElW0Q14kyY3KVUWAVpUTbfUPmtD6lo RO3EnoHDJoaak0yuw67Townpc9zRIBci3vUcUTh9SwUtv16b96DI92BRRu8XBaRU 13E33BWUkf6DebpYHmCmlwy3NelHfOtbzc2FBJ7Xt+hQnxd+07V2NgUNjMpCQrMD oh8ulOLWvrGKm7SZhV0ubqTt85mM6j5tmw0dkMwsGhgnf0U12uMfEKxm3IjcU+uk 0757WvPQQcr/iFSjxXwroqIgZpSJ/L1c8cfXgZ5bf0syeFODxEGISQQYEQIACQUC SjVERgIbDAAKCRBthXHBmOb+loxrAKDUB6CWC+kYIOaRmD9IvVfKosm9wgCeN4XV 3vIlH84xsRZ/rS/yfwggdDc= =jCPh -----END PGP PUBLIC KEY BLOCK-----