In April, Facebook unveiled a new technology called Instant Personalization. Initially released to just Yelp, Pandora, and Docs.com, Instant Personalization has been widely misunderstood by the media and Facebook users alike.
Instant personalization allows any site that Facebook chooses to partner with to use your current Facebook session as its own authentication system. In other words, if you are logged into Facebook when you visit Yelp.com, Yelp will immediately know who you are and some basic information about you (such as your profile photo and friends list) without any further action on your part.
From a more technical perspective: Instant personalization is a modification to the Facebook Open Graph API that allows certain partner sites to bypass the application authorization process prior to gathering information about the current user. The partner application simply loads an external script file hosted on Facebook's site, and Facebook returns an authentication key that the application can use to gather basic information about the user.
Many people may be perfectly fine with what I've described so far. Allowing Docs.com, Yelp.com, Pandora.com and now RottenTomatoes.com to gather my name, photo, and friends list when I visit them is not a big privacy concern to most users. In fact, Instant Personalization has been used to create a great user experience on all of these sites. It's neat to be able to see which restaurants my friends like on Yelp.com without ever needing to go through the effort of making a Yelp account and trying to rebuild my friends list.
Unfortunately, Instant Personalization also suffers from several fundamental security flaws that place all Facebook users at risk.
1. Vulnerabilities in Instant Personalization partner sites allow malicious 3rd parties to hijack authentication tokens.
On May 11, I created a demonstration of how this flaw could be abused such that malicious 3rd party sites could get access to private information. My discovery led to two articles on TechCrunch.com in the same day -- http://techcrunch.com/2010/05/11/yelp-security-hole-puts-facebook-user-data-at-risk-underscores-problems-with-instant-personalization/ and http://techcrunch.com/2010/05/11/another-security-hole-found-on-yelp-facebook-data-once-again-put-at-risk/.
As described in the articles above, my demonstration used a cross site scripting vulnerability in Yelp.com to hijack the authentication token that Yelp uses to get user information. Cross site scripting vulnerabilities are one of the most prevalent security issues on the internet. I would say with a high degree of confidence that all of Facebook's current instant personalization partners have cross site scripting vulnerabilities that have not yet been discovered.
Any cross site scripting vulnerability in any Instant Personalization partner site can be used by a malicious third party to find out your name, birthday, location, school, and work information as listed on Facebook unless you have specifically made this information private. The only action that you would need to take for this to happen is clicking a malicious link or seeing an ad created by this malicious third party. Yes, malicious advertisers now have the ability to collect all of this information about you while incorporating the names and pictures of your friends into their ads. As the Instant Personalization partnership program expands, these vulnerabilities only become easier to discover and exploit.
2. Third party content on Instant Personalization partner sites has access to authentication tokens.
Any third party Javascript tracking tools or advertising code can capture authentication tokens. As third party Javascript based tools such as Get Satisfaction or Google Analytics become more popular any of these tools could get access to instant personalization information. While I'm certain no reputable company would do this, less scrupulous advertisers should not be underestimated. The value of collecting the name, location, education information, and friends list from any user that views an ad is a gold mine for advertisers.
3. Authentication tokens are not sent securely.
Although the Facebook API requires that all API requests containing an authentication token are sent to Facebook over HTTPS, all Instant Personalization partner sites currently send the authentication token itself over plain HTTP inside of cookies or in the page source itself.
4. Instant Personalization partner sites are allowed to store data that they collect from the Facebook API indefinitely.
Five years from now all Instant Personalization sites may still know your name, your Facebook id, and everything you've ever done on them. Docs.com will know what documents you looked at, Yelp will know which restaurants you've been to, Pandora will know what music you listened to, and RottenTomatoes will know which movies you went to see. Information that you previously had to opt in to sharing via signup or login forms is now shared by default and tied to you forever. None of these sites has an easy way for users to delete this collected information.
---
On August 26, Facebook announced that they would be working to launch instant personalization with more partners, with a focus on providing it to startups in the YCombinator venture firm: http://techcrunch.com/2010/08/26/facebook-y-combinator/. As more and more Instant Personalization partners are announced, the severity of the security flaws I described only grows worse.
While it's hard not to see the tremendous value that Instant Personalization provides for it's partners and their users, we should not ignore the security and privacy risks it presents. The technical complexity of Instant Personalization has made it difficult to understand the risks it presents, and the simultaneous launch of Facebook's Social Plugins has only further confused users and the media. It's essential that all users become aware of the risks and make an informed decision on whether they should opt-out of instant personalization.
The opt-out page for instant personalization can be found here: http://www.facebook.com/settings/?tab=privacy§ion=applications&field=instant_personalization
Like this post? Please vote it up on YCNews: http://news.ycombinator.com/item?id=1727717
Saturday, September 25, 2010
Thursday, September 9, 2010
Reverse engineering the latest Facebook worm
Earlier today I noticed several of my friends had been hit by a Facebook worm that updated their status, created an event, and finally invited all of their friends to the event. The purpose of the worm was to widely distribute several "work from home" and similar scams. All of this happened instantly when they clicked on a link that they had seen posted by another user that had fallen for the trap. Knowing that Facebook would fix the issue soon, I immediately opened up my HTTP debugging tools and set about discovering how it worked.
Step 1: The user clicks a shortened url posted by a friend that has been hit by the worm. Each victim's status is updated with a new shortened url, and multiple URL shorteners are used.
Step 2: The user is redirected to one of many domains. In my case it was http://vidxapp3.co.cc/joblp/?go=973
Step 3: The exploit site loads an iframe to one of many facebook applications that have been set up by the attacker. The facebook application to use is chosen randomly from a large list to make the exploit more difficult to stop.
The Facebook application is built using FBML and FBJS, a special markup language and JavaScript variant designed to allow Facebook application developers to write applications that run inside of Facebook's context. This is done by disallowing harmful tags, prefixing all ID attributes with the application id, and only allowing developers to use a small set of custom JavaScript getter and setter functions to interact with the part of the DOM that belongs to the application.
In addition to disallowing certain tags, FBML provides the developer with the ability to use special tags such as the Like button. These tags are turned into HTML prior to being served to the user's browser, and a sandboxing method is employed to prevent FBJS from accessing them (To click the like button without the user's permission, for example). The sandboxing method essentially consists of applying an attribute to the HTML that tells the FBJS getter methods provided to developers that they should not be allowed to fetch the element via getElementById or any other methods.
Step 4: The malicious Facebook application makes a Ajax request through Facebook's servers to load additional FBML.
Due to an error on Facebook's part, the developer is able to get around the normal FBJS sandboxing methods for the like button using code essentially like the following:
You likely see the problem here. The <fb:like> FBML tag will generate HTML that will contain the HTML attributes that instruct FBJS to disallow access to it, but that won't matter because the HTML simply gets rendered as text inside the textarea.
Step 5: The malicious application uses FBJS to parse the HTML generated from the like button and steal the CSRF protection tokens from it (You can read more about CSRF here).
Here's the code (Cleaned up slightly from the modifications Facebook's FBJS parser makes to try to sandbox it):
You can see that the FBJS code steals two CSRF protection keys. One is fb_dtsg, and the other is post_form_id. These keys are then used to set the source of an iframe to a URL such that the attacker now has access to those keys.
Step 6: The attacker's iframe makes a request to http://westernshowercurtains.info/app/golike.php?p=4490d3098311ba39ba6db0932c3310e1&d=_xURo
Which uses CSRF to make the user Like (fan) a page:
Step 7: The attacker's iframe makes a request to http://westernshowercurtains.info/app/gostatus.php?p=4490d3098311ba39ba6db0932c3310e1&d=_xURo which updates the user's status using the following code:
Step 8: The attacker's iframe makes a request to http://westernshowercurtains.info/app/goauth.php?app=159222847426674&p=4490d3098311ba39ba6db0932c3310e1&d=_xURo which authorizes the Facebook application using the following code:
If you look carefully, you'll notice that the application will now be granted permission to publish to stream, create an event, and RSVP for events.
After step 8, Facebook reads the next parameter from the form and redirects the user to step 10 at http://westernshowercurtains.info/app/gomessage.php?p=4490d3098311ba39ba6db0932c3310e1&app=159222847426674&d=_xURo.
Step 9: The application creates an event on the user's behalf and invites all of their friends (server side)
Step 10: This user is redirected to a page with another CSRF form to spam all of their friends with messages.
---
Facebook patched the security flaw used by this worm shortly after it was discovered. FBML tags inside of textareas are now no longer converted to HTML.
This was a particularly interesting worm due to the use of an FBML flaw as an attack vector. Approximately a year ago I reported a similar issue due to improper sand-boxing of FBJS Dialog boxes. As with many technologies as complex as FBML, they can provide an excellent method of attack for hackers that are willing to learn their way around them.
Perhaps wisely, Facebook has chosen to move away from FBML canvas applications. Until then, hopefully we won't see too many more of these vulnerabilities discovered by the bad guys.
Like this post? Please vote it up on YC News.
Step 1: The user clicks a shortened url posted by a friend that has been hit by the worm. Each victim's status is updated with a new shortened url, and multiple URL shorteners are used.
Step 2: The user is redirected to one of many domains. In my case it was http://vidxapp3.co.cc/joblp/?go=973
Step 3: The exploit site loads an iframe to one of many facebook applications that have been set up by the attacker. The facebook application to use is chosen randomly from a large list to make the exploit more difficult to stop.
The Facebook application is built using FBML and FBJS, a special markup language and JavaScript variant designed to allow Facebook application developers to write applications that run inside of Facebook's context. This is done by disallowing harmful tags, prefixing all ID attributes with the application id, and only allowing developers to use a small set of custom JavaScript getter and setter functions to interact with the part of the DOM that belongs to the application.
In addition to disallowing certain tags, FBML provides the developer with the ability to use special tags such as the Like button. These tags are turned into HTML prior to being served to the user's browser, and a sandboxing method is employed to prevent FBJS from accessing them (To click the like button without the user's permission, for example). The sandboxing method essentially consists of applying an attribute to the HTML that tells the FBJS getter methods provided to developers that they should not be allowed to fetch the element via getElementById or any other methods.
Step 4: The malicious Facebook application makes a Ajax request through Facebook's servers to load additional FBML.
Due to an error on Facebook's part, the developer is able to get around the normal FBJS sandboxing methods for the like button using code essentially like the following:
You likely see the problem here. The <fb:like> FBML tag will generate HTML that will contain the HTML attributes that instruct FBJS to disallow access to it, but that won't matter because the HTML simply gets rendered as text inside the textarea.
Step 5: The malicious application uses FBJS to parse the HTML generated from the like button and steal the CSRF protection tokens from it (You can read more about CSRF here).
Here's the code (Cleaned up slightly from the modifications Facebook's FBJS parser makes to try to sandbox it):
You can see that the FBJS code steals two CSRF protection keys. One is fb_dtsg, and the other is post_form_id. These keys are then used to set the source of an iframe to a URL such that the attacker now has access to those keys.
Step 6: The attacker's iframe makes a request to http://westernshowercurtains.info/app/golike.php?p=4490d3098311ba39ba6db0932c3310e1&d=_xURo
Which uses CSRF to make the user Like (fan) a page:
Step 7: The attacker's iframe makes a request to http://westernshowercurtains.info/app/gostatus.php?p=4490d3098311ba39ba6db0932c3310e1&d=_xURo which updates the user's status using the following code:
Step 8: The attacker's iframe makes a request to http://westernshowercurtains.info/app/goauth.php?app=159222847426674&p=4490d3098311ba39ba6db0932c3310e1&d=_xURo which authorizes the Facebook application using the following code:
If you look carefully, you'll notice that the application will now be granted permission to publish to stream, create an event, and RSVP for events.
After step 8, Facebook reads the next parameter from the form and redirects the user to step 10 at http://westernshowercurtains.info/app/gomessage.php?p=4490d3098311ba39ba6db0932c3310e1&app=159222847426674&d=_xURo.
Step 9: The application creates an event on the user's behalf and invites all of their friends (server side)
Step 10: This user is redirected to a page with another CSRF form to spam all of their friends with messages.
---
Facebook patched the security flaw used by this worm shortly after it was discovered. FBML tags inside of textareas are now no longer converted to HTML.
This was a particularly interesting worm due to the use of an FBML flaw as an attack vector. Approximately a year ago I reported a similar issue due to improper sand-boxing of FBJS Dialog boxes. As with many technologies as complex as FBML, they can provide an excellent method of attack for hackers that are willing to learn their way around them.
Perhaps wisely, Facebook has chosen to move away from FBML canvas applications. Until then, hopefully we won't see too many more of these vulnerabilities discovered by the bad guys.
Like this post? Please vote it up on YC News.
Labels:
cross site scripting,
facebook,
hacking,
reverse engineering
Tuesday, September 7, 2010
Watch out for vulnerabilities in 3rd party applications on your site's domain.
In the past few years it has become common for site owners to run 3rd party tools on their site. A good example would be Wordpress or other blogs, installations of which are typically located on a subdomain such as http://blog.example.com. Often times these addons are not even hosted by the site owner, instead they are hosted by the third party and the domain owner simply sets up a DNS CNAME record to direct traffic. Recall that any subdomain can set its document.domain to any right hand qualified fragment of its domain in order to obtain permissions through the same origin policy. Many sites now set their document.domain to the top level domain, thereby allowing any scripts running on subdomains to obtain same origin access to anything on the site.
Despite its danger, this practice is so widespread that even Facebook was known for doing it frequently. I say that in the past tense because I was able to take advantage of this to find multiple cross site scripting vulnerabilities affecting http://facebook.com. After I reported the issues Facebook performed a complete audit of everything hosted on their subdomains. As a result, sites like the developer forum and bugzilla have been moved to Facebook.net.
It all started when I noticed that Facebook had once set up a UserVoice (http://www.uservoice.com) account, accessible via http://feedback.developers.facebook.com but hosted by UserVoice. At some point they had chosen to close their account, but they left the domain settings untouched.
I followed the following process to craft a proof of concept exploit:
In this case, Facebook was able to fix this vulnerability simply by disabling the http://feedback.developers.facebook.com domain.
I also notified UserVoice about this issue, along with a related issue that would allow a hacker to hijack the sessions of UserVoice users. Here was their response:
Next, I was able to identify multiple publicly disclosed cross site scripting vulnerabilities present in the outdated version of Bugzilla once located at http://bugs.developers.facebook.com (now moved to http://bugs.developers.facebook.net). As with the UserVoice exploit, I was able to quickly craft the same session hijacking proof of concept exploit.
So what's the conclusion to all this? Don't allow your site to be exposed to vulnerabilities in 3rd party tools such as Wordpress, UserVoice, GetSatisfaction, Tumblr, etc. by hosting them on subdomains. If your primary site's document.domain is a top level domain then any vulnerability in a 3rd party site located on a subdomain is the same as a vulnerability in your site (And you have much less control over the security of 3rd party tools). The only case in which it is truly safe to host 3rd party applications on a subdomain is if your primary site uses a document.domain starting with "www" or similar.
Despite its danger, this practice is so widespread that even Facebook was known for doing it frequently. I say that in the past tense because I was able to take advantage of this to find multiple cross site scripting vulnerabilities affecting http://facebook.com. After I reported the issues Facebook performed a complete audit of everything hosted on their subdomains. As a result, sites like the developer forum and bugzilla have been moved to Facebook.net.
It all started when I noticed that Facebook had once set up a UserVoice (http://www.uservoice.com) account, accessible via http://feedback.developers.facebook.com but hosted by UserVoice. At some point they had chosen to close their account, but they left the domain settings untouched.
I followed the following process to craft a proof of concept exploit:
- Signed up for UserVoice
- Purchased the most expensive $500/Month account, with a 30 day trial. This account allows for custom HTML, Javascript, and domains.
- Configured the account to use the previously active http://feedback.developers.facebook.com domain. No confirmation process was required and UserVoice allowed me to take the domain even though it had been previously used by an inactive account.
- Wrote a proof of concept exploit which set the site document.domain to "facebook.com" and then hijacked the user's session.
In this case, Facebook was able to fix this vulnerability simply by disabling the http://feedback.developers.facebook.com domain.
I also notified UserVoice about this issue, along with a related issue that would allow a hacker to hijack the sessions of UserVoice users. Here was their response:
Hi George,
First of all thank you for bringing these issues to our attention and for working with us to get them sorted. Our next steps are to:
* Modify the way sessions are created so that they are site-specific (x.uservoice.com). Once a session is created on a specific subdomain it cannot be reused on any others.
* We will prevent any new account from using the cname of a previous account (even if it's been deleted).
We will have this in place before the 14th and I'll let you know when that's the case.
Thanks again,
Richard White
CEO, UserVoice.com
Next, I was able to identify multiple publicly disclosed cross site scripting vulnerabilities present in the outdated version of Bugzilla once located at http://bugs.developers.facebook.com (now moved to http://bugs.developers.facebook.net). As with the UserVoice exploit, I was able to quickly craft the same session hijacking proof of concept exploit.
So what's the conclusion to all this? Don't allow your site to be exposed to vulnerabilities in 3rd party tools such as Wordpress, UserVoice, GetSatisfaction, Tumblr, etc. by hosting them on subdomains. If your primary site's document.domain is a top level domain then any vulnerability in a 3rd party site located on a subdomain is the same as a vulnerability in your site (And you have much less control over the security of 3rd party tools). The only case in which it is truly safe to host 3rd party applications on a subdomain is if your primary site uses a document.domain starting with "www" or similar.
Labels:
cross site scripting,
facebook,
hacking
Subscribe to:
Posts (Atom)