I recently came across an article regarding a CSRF vulnerability on Facebook discovered by M.J. Keith. Keith documents how Facebook does not enforce the CSRF protection token “post_form_id”. He states that when it is omitted entirely from some of the requests, Facebook executes the request as if it wasn’t even required in the first place. A demo video is located on the site which shows how someone can exploit this flaw to seamlessly update a user’s Facebook profile information.

Although Facebook has reported that it has fixed this flaw, I decided to look into it a bit further.

After playing around with a few requests, I noticed that there still remains a CSRF vulnerability pertaining to the request used to delete a friend. By completely omitting the “post_form_id”, as well as a few other parameters, I noticed that Facebook will still carry out the deletion of the friend whose id was specified in the request. This allows an attacker to seamlessly delete specified friends from the currently logged in Facebook user by getting the user to visit a specially crafted web page.

I than began thinking if it would be possible to delete ALL the friends of the currently logged in Facebook user at once, just by making them visit a malicious web page. Being aware of Facebook’s privacy settings, I remembered that most users’ friend lists are public. Having done a little bit of Facebook application development in the past, I began looking into some of the old REST API calls to see if there was a quick and easy way to obtain the profile ids of each of the victim’s friends without authorization. I noticed that this was possible, but it required authorization from the user. Authorization is also necessary for the new API calls. I decided to do a raw HTML scrape of their friends list. After parsing out the id from each friend on the target’s friend list, I can then execute the user deletion request for the id of each of the victim’s friends.

The PoC that I wrote to demonstrate this uses Ajax to constantly fetch and parse waves of friend ids from the victim’s public friend’s list. It then dynamically creates an iframe in the DOM for each friend id gathered and uses the iframe’s source to pass the id to a another script. This script then populates a form with the appropriate request variables, then auto-submits the vulnerable request to Facebook, using javascript.  This process seamlessly loops in the background until all of the victim’s friends are deleted.

Below is a simple demo video demonstrating the CSRF vulnerability on a single friend.

*Update (5/22/10): After reporting the flaw to Facebook Wednesday afternoon, I have confirmed as of Friday afternoon that the flaw has been successfully patched. Facebook now strictly enforces the existence of the “post_form_id” CSRF protection token in the request. Hopefully they do this for all other serious requests as well. I have updated the above post with more details pertaining to the flaw, as well as my method of exploiting it.