In Defense of Walled Gardens

It’s easy to assume that when it comes to data and software development, “open” is always better than “closed.” We’ve seen an explosion of open source software, praised companies for supporting open standards, and breathlessly tracked products with “open” in their name, from OpenID to OpenSocial. “Closed” has become the scarlet letter of the Internet, at times expressed by the censure of being branded a “walled garden.”

Facebook has often faced this criticism, particularly after unveiling the Facebook Platform in 2007. Several bloggers compared Facebook unfavorably to AOL of yesteryear, eschewing Facebook’s “proprietary” (gasp!) FBML and FQL interfaces. Some even portrayed Facebook as a competitor to the Web itself. While the definition of “walled garden” was not always particularly clear, observers were unhappy with so much data flowing into Facebook and so little flowing out.

One would think that now, with the Facebook API able to expose your wall, News Feed, inbox, and just about every bit of profile data (even e-mail addresses to some degree) Facebook would be allowed in the open club. Indeed, some writers have noted changes since 2007 that justify dropping the dreaded horticultural moniker. But others continue to speak worriedly of Facebook’s dominance, even still drawing comparisons to AOL.

I, for one, not only have full confidence in the Web outlasting any supposed competition but also see Facebook as very much a part of that resilient network. In fact, I’d like to propose a bit of Internet heresy by according walled gardens a place among the open fields of the online realm.

First, let’s establish one fact: Facebook has always been part of, not opposed to, the Web. Disregard ridiculous arguments over FBML and FQL, which were no more of a threat to HTML and SQL than Smarty and WordPress template functions. Open any Facebook application, choose to “view source,” and all you’ll see is good ol’ HTML, CSS, and JavaScript. The Facebook Platform allowed developers to build on top of Facebook, just as Movable Type and Joomla allowed developers to write plug-ins using Perl and PHP. (Differences: you could not roll your own Facebook, Facebook essentially installed every plug-in, and you have to host the code.) That Facebook disallowed certain HTML security risks and added a few convenient tags for interfacing with their content in one approach to development (one could always write full-blown HTML using canvas iframes instead of FBML) hardly meant they were reinventing Web standards.

Technical considerations aside, some writers argued that Facebook opposed the Web in spirit – more specifically, the spirit of openness. Even though Facebook applications (and inverting Facebook’s criticized original setup, other web sites via Facebook Connect) have wide access to Facebook data now, average users still face hurdles if they wish to view posts and information from other Facebook users. At minimum, one has to create an account and login to Facebook to see beyond bare basics. Prior to recent privacy changes, access to content from non-friends was highly limited even after logging in. And while some of Facebook’s data should start appearing in search engines this year, very little has been indexed by Google so far. As I said before, users generate much content within the context of Facebook, but that context usually remains locked away from public access.

Before I respond directly to such charges, I’d note that Facebook (or any social networking utility) serves a limited purpose. Did you catch that? Facebook serves a limited purpose. Facebook was never meant to duplicate the Internet. If I need reference material on world history, I might turn to Google or (as a starting point) Wikipedia. If I want to know the latest technology news, I can bring up Techmeme. If I want to catch up on a favorite TV show, I’ll probably load Hulu. None of these tasks have any inherent social component that would cause me to first open Facebook when fulfilling them.

Last summer, however, I wrote a series of articles on particular doctrinal issues that affected certain people in churches and organizations I’ve been a part of. I’m not ashamed of my opinions, but they involve points that would not make sense to someone who did not have the background and context of the limited audience I had in mind when writing. Consequently, I would prefer such musings did not appear in the Google search results of an acquaintance unfamiliar with my topics. I shared my thoughts with certain friends via Facebook Notes.

I have friends who live several states away that wish to keep me and others posted on life in their growing family. They want to share what adventures their children are having with extended family across the country. Friends desire to see how they’ve decorated their new home and exchange tips on managing it. Rather than open themselves to potential hazards of their house and kids being featured in an image search, my friends can use Facebook’s photo albums to control who can observe their daily life.

These are but two use cases out of a hundred or more that (1) inherently involve a user’s social graph and (2) inherently involve content not intended for public consumption. To argue that Web-based services other than Facebook could provide similar functionality in an open context misses the point. Yes, I could have published my articles with Blogger, my friends could post their photos on Flickr. But these particular examples are not simply about sharing ideas and pictures – they involve sharing ideas and pictures with certain people.

Are you dissatisfied with Facebook limiting access to content? That’s where the rest of the Web (again, Facebook is one part of the Web) comes in handy. If you’re a blogger who wants the world to hear your thoughts, forget Facebook and start a blog. If you’re a photographer who wants to advertise your portfolio, forget Facebook and use a more open service. If you’re looking to interact with a small subset of the world, however, a walled garden may be just the thing for you.

Of course, these days Facebook’s leadership may cringe at my last paragraph, as they seem to be taking a new angle on their service’s purpose. But a few years ago, privacy and control (in essence, the very things that made it a “walled garden”) are what distinguished Facebook from competitors. Personally, I have trouble buying Mark Zuckerberg’s story that “if he were to create Facebook again today, user information would by default be public” (ReadWriteWeb), as such a site really wouldn’t have been much on an innovation. Recall that prior to Facebook’s rise, MySpace dominated social networking sites, and many (if not most) MySpace profiles were publicly accessible. Limitations are what made Facebook novel – originally, only college students were even allowed to create profiles on the site, and all profiles followed a strict layout.

In my experience, friends flocked to Facebook because it let them participate in new technologies (sharing digital photos, for instance) but in a controlled environment where they could enjoy a level of privacy. The garden walls were selling points – college students didn’t want just anyone seeing their photos and messages; later on, parents didn’t want their teenagers communicating with just anyone. I think that’s partly why Facebook’s recent moves encouraging users to share more openly generated such controversy. Users felt they had fallen victim to a “bait and switch” scheme: they invited their friends to use Facebook so they could share privately, now suddenly Facebook has forced them to share certain information and is pushing them to share the rest.

It’s also worth noting that in its early days, Facebook offered little functionality that couldn’t be found elsewhere. The notion of a profile, the ability to send private messages, the exchange of ideas centered around certain topics – all of these features were hallmarks of forum sites for years. But while the members of a forum formed a particular social graph centered around a certain niche community, Zuckerberg portrayed a user’s social graph on Facebook as a mirror of their everyday, real-life connections. Facebook (and other sites, such as MySpace) took the features of forums and adapted them for a general purpose audience, where you essentially chose the members of your forum based on who you already communicated with offline.

This brings us back to Facebook’s limited purpose and why some of the hand-wringing over its “proprietary” nature strikes me as overreacting. For instance, back in 2007, Gervase Markham of the Mozilla Foundation expressed concern that the messaging system in Facebook or LinkedIn might turn e-mail into a closed system incompatible with outside domains – in short, a walled garden. But Facebook messages could never replace SMTP e-mail. If I want to interact with close friends, Facebook messages provide a convenient, hassle-free means of doing so. Yet if I need to exchange notes or documents with acquaintances, large groups, or even businesses, Facebook messages are hardly up to the task. Once again, such use cases do not involve my social graph. I think Facebook recognized this as they expanded and started trying to juggle multiple social graphs beyond a user’s closer friends, since messages from fan pages (essentially, communications for a business) are filed away in a folder quite separate from a user’s main inbox of messages.

All this being said, please don’t think I’m opposed to more “open” approaches to handling my social graph, such as distributed social networking – far from it. I think Facebook is still an early player in online social networking, and that we’ll see many more platforms and ideas develop in years to come. But I think we’re still a long way from a time where the open alternatives provide end users with more value than walled gardens in the types of use cases I’ve already outlined. As much as I’d like to see federated social networking platforms thrive, I foresee many hurdles that have yet to be overcome. Distributed networks will have to deal with issues relating to performance (imagine generating a news feed when your friends’ data comes from hundreds of different servers), retention (is data cached, how long, etc.), reliability (what happens when a few of your friends’ servers are down?), privacy (how will access be controlled and monitored), and security (avoiding injection attacks, ensuring all hosts stay up-to-date, etc.), not to mention monetization (a problem that still plagues closed systems). And when it comes to user value, remember that walled gardens have a few inherent advantages – in a security example, if Facebook detects a worm spreading malicious links via messages, they can block all messages with a certain signature or strip out links to a known rogue site.

I suppose my main point is that we need not be concerned if Internet users (even 350 million of them) find use for a service that strikes many technology-minded people as a walled garden. While the Internet was built on open, equal access, that very setup enables some services to provide certain features in a more limited context while still taking advantage of Web technologies. And for many people, these gated communities provide real value that would actually diminish if Google began indexing it all. While certain circles seem to think any notion of online privacy is at best naïve (and granted, some users need to exercise more caution in what they post online, regardless of what service they use), I tend to think that the only people saying privacy is dead are those named in its will. And when privacy does become a factor in sharing online, at times, a garden might need walls.

P.S.: Lest you think I’ve changed my opinion in light of recent privacy controversies, I’d note that I stated very similar thoughts back in 2007 when some of these debates over Facebook first developed.

Facebook StumbleUpon Digg Twitter Instapaper FriendFeed Delicious Google Bookmarks Share/Bookmark

Facebook Applications are Now Even More Valuable Hacking Targets

I’ve demonstrated countless times over the past year that cross-site scripting vulnerabilities in Facebook applications can be exploited to make Facebook API requests on behalf of the application. This type of attack, which I called a FAXX hack, enables one to not only post links to Facebook for viral effects but also harvest a wealth of information on victimized users along the way, such as name, date of birth, interests, family members, photos, and so on. However, contact information lay outside the scope of available data.

Until now. Facebook has launched a new Platform feature that enables developers to request e-mail addresses from their users. An unfortunate side effect of this behavior is that Facebook applications have now become more promising targets for online attacks.

Over time, it’s likely that popular applications will routinely request e-mail addresses from users, meaning eventually certain applications could have millions of addresses saved. (Note that Facebook allows developers to store e-mail addresses indefinitely under this new setup.) One SQL injection hole could potentially compromise all of those e-mail addresses. Also, if the application had an XSS vulnerability, one could easily launch a FAXX attack that requests e-mail addresses from Facebook via FQL.

This certainly all depends on several factors, one being whether many users embrace sharing their e-mail addresses with applications. Some may question whether finding an exploitable vulnerability in a popular application would be likely, but based on last year’s Month of Facebook Bugs, I think the odds are not encouraging.

My recommendation to users would be against letting applications have your e-mail address; Facebook does provide a proxy system if you really want messages. But I do hope this new feature will bring more attention to issues of security on the Facebook Platform.

Facebook StumbleUpon Digg Twitter Instapaper FriendFeed Delicious Google Bookmarks Share/Bookmark

Backup or Export Your Facebook Account

Update

This post has been superseded by “An Updated Guide to Backing up or Exporting Your Facebook.” Please refer to the new post for more current instructions and disregard the information below.

Original Post

Last update: 4 Jan 2010, 4:56PM EST

Introduction

Over the last several years, I’ve seen several technology analysts criticize Facebook for not giving users greater control over their data. Many have commented that while it’s simple for data to flow into Facebook, getting data back out can prove much harder. In the ensuing debate, various issues can get oversimplified – after all, Facebook has a business interest in keeping users, and friends create some of the data users may want to export.

But while Facebook provides few official options for users wanting to export or backup their information and activity on the site, they have steadily widened the amount of data available to third-party applications via their API over the last year or so. Consequently, users with a little technical know-how can use the API to download a wealth of information. This makes it entirely possible to create an archive of your Facebook account.

I do not believe anything I’m about to share violates Facebook’s Terms of Service, since I am simply providing tips for users to more easily download information already available to them via facebook.com for their own personal and archival use. The methods presented here do not require any techniques that avoid or work around Facebook’s official APIs.

Among the interfaces developers can use to access Facebook data, one involves sending FQL (Facebook Query Language) queries to Facebook. These FQL statements resemble standard SQL requests against a set of database tables containing user information. If you’re logged in to Facebook, you can execute FQL queries right now by visiting Facebook’s API Test Console and setting the method to “fql.query”.

With that test console, you can request most of your Facebook account information and simply copy-paste the results to a text file for your own use. In my testing, I set the response format to JSON for two reasons. First, I’m more familiar with handling Facebook information in JavaScript, so JSON is an easier format for me to work with. Second, JSON is far more compact than XML, producing much smaller responses and backup file sizes.

I’ve put together a series of 21 FQL queries that together provide a fairly complete backup/export of a Facebook user’s account. Fifteen All but six of these queries can be executed using the API Test Console without any further effort. The others can only be made from an application with certain extended permissions. Developers familiar with creating Facebook applications can enable these permissions using the following two URIs, replacing “ffffffffffffffffffffffffffffffff” with an application’s API key:

  • http://www.facebook.com/authorize.php?api_key=ffffffffffffffffffffffffffffffff&v=1.0&ext_perm=read_mailbox
  • http://www.facebook.com/authorize.php?api_key=ffffffffffffffffffffffffffffffff&v=1.0&ext_perm=read_stream

After authorizing an application you administer, you can return to the API Test Console and specify the authorized application for making API requests. This allows you to all of the FQL queries via console and not have to worry about creating code to issue the requests. Please note that I make no warranties or guarantees about using this information – I provide these tips merely as a helpful resource to users who are interested in exporting their data. I cannot guarantee this will work for you, and I cannot promise any support if you have trouble getting these tips to work for you.

The 21 Queries

Here now are the FQL queries, each with a short description. For each query, replace 00000000 with your Facebook ID number.

  1. Profile information of friends (note that friends may limit this data via their application privacy settings) (Update 3; added “quotes” on 3 Jan 2010): SELECT uid, first_name, last_name, name, pic_big, affiliations, religion, birthday, birthday_date, sex, hometown_location, political, current_location, activities, interests, music, tv, movies, books, quotes, about_me, hs_info, education_history, work_history, profile_url, profile_blurb, family, username, website FROM user WHERE uid IN (SELECT uid2 FROM friend WHERE uid1 = 00000000)
  2. Events you have attended: SELECT eid, name, tagline, pic_big, host, description, event_type, event_subtype, start_time, end_time, creator, location, venue FROM event WHERE eid IN (SELECT eid FROM event_member WHERE uid = 00000000 AND rsvp_status = “attending”)
  3. Your friend lists: SELECT flid, name FROM friendlist WHERE owner = 00000000
  4. The members of your friend lists: SELECT flid, uid FROM friendlist WHERE flid IN (SELECT flid FROM friendlist WHERE owner = 00000000)
  5. Your notes: SELECT note_id, title, created_time, content FROM note WHERE uid = 00000000
  6. Comments on your notes: SELECT object_id, post_id, fromid, time, text FROM comment WHERE object_id IN (SELECT note_id FROM note WHERE uid = 00000000)
  7. Pages you’re a fan of: SELECT page_id, name, pic_big, website, type FROM page WHERE page_id IN (SELECT page_id FROM page_fan WHERE uid = 00000000)
  8. Links you have posted: SELECT link_id, owner_comment, created_time, title, summary, url, image_urls FROM link WHERE owner = 00000000
  9. Threads in your inbox (requires “read_mailbox” permissions): SELECT thread_id, folder_id, subject, recipients, updated_time, parent_message_id, parent_thread_id, message_count, snippet, snippet_author, object_id FROM thread WHERE folder_id = 0
  10. Threads in your outbox (requires “read_mailbox” permissions): SELECT thread_id, folder_id, subject, recipients, updated_time, parent_message_id, parent_thread_id, message_count, snippet, snippet_author, object_id FROM thread WHERE folder_id = 1
  11. Messages in your inbox (requires “read_mailbox” permissions): SELECT message_id, thread_id, author_id, body, created_time, attachment FROM message WHERE thread_id IN (SELECT thread_id FROM thread WHERE folder_id = 0)
  12. Messages in your outbox (requires “read_mailbox” permissions): SELECT message_id, thread_id, author_id, body, created_time, attachment FROM message WHERE thread_id IN (SELECT thread_id FROM thread WHERE folder_id = 0)
  13. Your wall posts (requires “read_stream” permissions): SELECT post_id, app_id, source_id, updated_time, created_time, attribution, actor_id, target_id, message, app_data, action_links, attachment, comments, likes, privacy, permalink, tagged_ids, is_hidden FROM stream WHERE source_id = 00000000
  14. Comments on your wall posts (requires “read_stream” permissions): SELECT post_id, fromid, time, text FROM comment WHERE post_id IN (SELECT post_id FROM stream WHERE source_id = 00000000)
  15. Your photo albums: SELECT aid, cover_pid, name, created, modified, description, location, size, link, visible, modified_major, type, object_id FROM album WHERE owner = 00000000
  16. Comments on your photo albums: SELECT object_id, post_id, fromid, time, text FROM comment WHERE object_id IN (SELECT object_id FROM album WHERE owner = 00000000)
  17. Your photos: SELECT pid, aid, src_big, src_big_height, src_big_width, link, caption, created, modified, object_id FROM photo WHERE aid IN (SELECT aid FROM album WHERE owner = 00000000)
  18. Comments on your photos: SELECT object_id, post_id, fromid, time, text FROM comment WHERE object_id IN (SELECT object_id FROM photo WHERE aid IN (SELECT aid FROM album WHERE owner = 00000000))
  19. Your videos: SELECT vid, title, description, thumbnail_link, embed_html, updated_time, created_time FROM video WHERE owner = 00000000
  20. Comments on your videos: SELECT object_id, post_id, fromid, time, text FROM comment WHERE object_id IN (SELECT vid FROM video WHERE owner = 00000000)
  21. Groups you’re a member of: SELECT gid, name, nid, pic_big, description, group_type, group_subtype, recent_news, creator, update_time, office, website, venue, privacy FROM group WHERE gid IN (SELECT gid FROM group_member WHERE uid = 00000000)
  22. People tagged in your photos (Update 2; added 2 Jan 2010): SELECT pid, subject, text, xcoord, ycoord, created FROM photo_tag WHERE pid IN (SELECT pid FROM photo WHERE aid IN (SELECT aid FROM album WHERE owner = 00000000))
  23. People tagged in you videos (Update 5; added 4 Jan 2010): SELECT vid, subject FROM video_tag WHERE vid IN (SELECT vid FROM video WHERE owner = 00000000)

Notes

  • These queries produce JSON (or XML) data that can then be parsed by code written to handle them. The results are not in a format (such as CSV) that can be immediately opened as a spreadsheet. If you are expecting files you can easily read and edit, you will probably be disappointed.
  • Note that this does not provide you with direct contact information for your friends (e.g. e-mail addresses, phone numbers, etc.) as one cannot access such data via the Facebook API. This is a limitation imposed by Facebook that I can’t get around without breaking the TOS. (Addendum: The URI http://www.facebook.com/friends/?filter=pfp lets you pull up all your friends’ phone numbers, which would be fairly easy to copy-paste.)
  • Update 1: A little more investigation reveals that you can save all of your friends’ phone numbers in a JSON format by visiting this URI: http://www.facebook.com/friends/ajax/superfriends_phonebook.php?__a=1 The “payload” parameter lists the phone numbers, sorted by each friend’s Facebook ID number.
  • These queries only yield metadata about photos and videos, not the actual files. If you want to backup the photos and videos themselves, you will either need to load them using the URIs in the query results or use a service designed to backup such information.
  • I’ve chosen at this point to only include queries for photos and videos you’ve actually posted. It’s possible to request all photos or videos you’ve tagged in, but that starts raising more questions about the type of information you’re saving, as well as creating duplicate results for photos of yourself that you’ve uploaded.
  • Not all of these queries return all possible fields for a given FQL table. I have made selections regarding what I thought would be the most useful fields and what would yield reasonable response sizes. While I tried to make each request complete enough to represent a backup of the relevant information, you may disagree with my choices.
  • Update 4: I originally said that the query for friends’ profile information could be limited based on friends’ application privacy settings. However, I’ve since discovered that using the Test Console as the requesting application allows access to all information visible to the user. Remember, application privacy settings only apply to applications you’ve not authorized but your friends have authorized. Apparently, Facebook operates as though every user has authorized the Test Console.
  • Some of these requests may generate very large responses, so wait a few minutes if the results do not appear right away. In some cases, you may need to limit requests (i.e. adding “LIMIT 1,500″ for the first 500 results, “LIMIT 501,1000″ for the second 500, etc.). I tested the first query against an account with about 700 friends and did eventually receive a response using the Test Console, but it was about 1.2MB of data.
  • In my testing, the responses to these queries were complete, with one apparent exception. The query for comments on wall posts seemed to include only recent comments. I haven’t investigated the issue much yet but will post any updates if I find more information on the issue.
  • Please feel free to send questions or feedback to me (my e-mail is theharmonyguy on Gmail), but realize I may not be able to provide technical support if you’ve never used FQL or worked with JSON data. This is not a general solution for non-technical users by any stretch, but it at least provides an option for backing up Facebook information that’s more complete than other methods I’ve seen elsewhere.

Facebook StumbleUpon Digg Twitter Instapaper FriendFeed Delicious Google Bookmarks Share/Bookmark

10 Basic Concepts of Facebook Privacy

  1. Your name, your profile picture, your gender, your current city, the networks you’re in, who you’re friends with, and the pages you’re a fan of are available to anyone. These are known as publicly accessible information (PAI). You have no control over this.
  2. Any other piece of content marked visible to “Everyone” in your privacy settings is available to anyone. You have control over this.
  3. Any Facebook application or web site using Facebook Connect that you visit can access your PAI and content marked visible to “Everyone” in your privacy settings. You have no control over this.
  4. Any Facebook application you log in to or web site that you connect with your Facebook account can access all of your profile information (except for contact information), photos, videos, notes, events, groups, links, and notifications, regardless of your privacy settings. You have no control over this.
  5. Any Facebook application your friends log in to or web site your friends connect with their Facebook account that you have not also logged in to or connected with can access your information and content based on your application, profile, and content privacy settings. You have control over this.
  6. Any wall post a Facebook application or web site using Facebook Connect makes on your profile is visible to anyone who can view your wall. You have no control over this.
  7. Any change to profile information or feedback on content will generate a story on your wall visible to anyone who can also access the information or content. You have no control over this.
  8. Profile information, photos, videos, and notes are visible to other users based on your profile and content privacy settings. You have control over this.
  9. Events you’re invited to are visible to other users who can also view the event. You have no control over this.
  10. Past status updates and links are visible to other users based on the privacy setting used when posted. You have no control over this.

Facebook StumbleUpon Digg Twitter Instapaper FriendFeed Delicious Google Bookmarks Share/Bookmark

Easily View Hidden Facebook Friend Lists

Amid all the festivities of the Christmas season, the time off from other responsibilities has given me some more time to pursue one of my hobbies: hacking. (Or at least trying to hack – much of what I do would probably not be considered true “hacking” by many.)

Lately I’ve demonstrated how various data on Facebook, such as photo albums and events, can be accessed by anyone when most users would probably think otherwise. You can now add friend lists to that category of data.

You may recall that when Facebook rolled out their new privacy settings, many analysts complained about the list of who a user had “friended” becoming part of what Facebook classified as Publicly Available Information. In response, Facebook added a setting to remove the lists from a user’s profile, a move that seemed to quell some of the criticism.

But Facebook also made one point clear about friend lists: “This information is still publicly available, however, and can be accessed by applications” (Source: CNET). Since Facebook still considers friend lists to be PAI, I do not consider the details I’m about to publish a vulnerability and therefore feel free to disclose them.

Replace USERID in the following URI with a Facebook user’s ID number (e.g. Mark Zuckerberg’s is 4) and load the URI: http://www.facebook.com/ajax/typeahead_friends.php?u=USERID&__a=1 You’ll see a chunk of JSON that includes a list of the user’s friends, including names and profile links. The list is sorted by friends’ ID numbers. By the way, you don’t even need to be logged into Facebook for this trick to work. (Interestingly enough, I had come across a similar technique years ago, forwarded details to Facebook, then forgot about it; I wonder if this would have worked even prior to the new privacy controls.)

Once again, if you’re using Facebook, make sure you understand what information is available to everyone. (And have a merry Christmas! :)

Facebook StumbleUpon Digg Twitter Instapaper FriendFeed Delicious Google Bookmarks Share/Bookmark

Months Later, Old Facebook Privacy Problems Remain

I’ve tried. I’ve tried to give Facebook the benefit of the doubt. I’ve tried to look at the positive aspects of their service. I’ve tried to bring attention to issues and wait for solutions. I’ve tried to provide solutions. But tonight, I’m ready to give up on Facebook. After all the privacy and security problems I’ve seen with the Facebook Platform, I have to conclude that you should consider every action you take and all the content you post on Facebook to be public. If that bothers you, stop using Facebook.

Some might contend that this is the Internet we’re talking about – it’s supposed to be public. Partially true, but many web sites provide services intended for private use. I can use the Internet to check my bank account balance, open a new credit card, and contact my doctor. None of those are public activities. While I’m not naive enough to think that any online activity can be considered 100% secure, I can accept services that provide a reasonable level of privacy and security.

At one time, Facebook fell into that category. I used it to communicate with friends about my life and their lives. I exchanged messages, photos, and ideas never intended for public consumption. All the while, I relied on Facebook’s legendary privacy controls to ensure my content reached its intended audience only. Originally, Facebook didn’t simply discourage you from public sharing – it wasn’t even possible. You could hardly even communicate with people who had not approved you accessing their profile.

Eventually, Facebook introduced the Facebook Platform and began shifting priorities. They faced controversies along the way, from deceptive ads to the failed Beacon program. Most recently, they rolled out new privacy settings which many have criticized. In the midst of all these stories, I’ve spent time sifting through both news reports and code to understand what exactly was happening with my data. This started as little more than a hobby, but eventually it became more serious as I made some disturbing discoveries.

One such discovery involved noticing that advertisements in applications were making requests to the Facebook API for user information. The ad network queries were broad in scope and used to target ads more effectively. I first wrote about problematic ads in June of 2008, but the first time I confirmed that ads were exploiting the Facebook API came in June of this year. I discovered that applications were leaking a “session secret” to ad networks, allowing the ads to hijack application credentials and access user data.

Once I understood the power of a session secret, I began exploiting previous cross-site scripting vulnerabilities I’d uncovered to access user information. One of these holes dated back to at least February 2008. This initial work eventually led to the Month of Facebook Bugs, which spanned September of this year. The project demonstrated XSS issues affecting over 9,700 Facebook applications, all of which could be exploited to access user information (FAXX hacks). The list included many top applications, including ones supposedly verified by Facebook.

I’ve seen Facebook claim that they monitor API requests to avoid rogue applications harvesting user data. But after watching ad networks make broad requests for weeks, I had trouble seeing how they were being proactive. Similarly, while Facebook worked to patch all of the holes I reported in September, they would often give developers my contact information for help with the issues, and were quite obviously not actively watching for XSS problems in applications.

But as I said, I’ve tried to give Facebook the benefit of the doubt. When it came to problematic advertisements, Facebook seemed to take some action, and more recently I’d thought the old problems were essentially gone. As for application security, some could argue that it’s not Facebook’s responsibility to monitor application issues. However, with the brand association of the Platform and application XSS holes exposing loads of user data, Facebook owes it to their users to prevent more FAXX hacks from appearing.

I give that lengthy recap to explain what I report next. On day 25 of the Month of Facebook Bugs, I posted a vulnerability in an application called Photos I Love. At the time, it had just over one million monthly active users. The hole remained live for about a week after I first reported it, but eventually it disappeared. Photos I Love now has more than 2.3 million monthly active users.

But it also still has some of the same ads I criticized back in June. The application loads advertisements from SocialCash, and while the ads do not display and profile pictures or names, the code for the ads does load most of the information in a user profile. This code is executed within the context of the page, so the data is not necessarily sent back to SocialCash, but a few bits are definitely sent back, and with a few code changes by SocialCash it could all be sent back. In fact, SocialCash does receive a session secret via referrer URIs, and I’ve repeatedly demonstrated that such a setup allows for the full range of session secret API requests.

Even worse, the application still loads an iframe for SocialReach, one of the first ad networks banned by Facebook. The SocialReach iframe doesn’t actually display any ads, but it does load code with a session secret that makes broad API requests to Facebook. Fortunately, these requests currently fail, likely due to a mishandling of the session secret, but once again, a few code changes by SocialReach would start the data flowing again. Finally, the session secret is also leaked to affiliate marketer Gratis Network via referrer URIs.

After these rather appalling discoveries, I poked around Photos I Love a little more, and within minutes found another cross-site scripting vulnerability that could be exploited to hijack application credentials and access user information. I’ve found several FAXX hacks in applications since September, and the Facebook Platform Policy Team even asked once if they could copy me on e-mails to developers so that I could confirm patches directly. I wrote this in reply:

I don’t mind you cc’ing me on e-mails to developers, but I couldn’t make any guarantees on how much time I’d be able to invest re-checking holes or helping developers out with details. I view these reports as a courtesy, and try to provide enough details for you to verify where the vulnerabilities occur. Again, I don’t mind helping and am not trying to hurt anyone, but I’m also doing all of this as volunteer work and have other projects that take priority. And while I don’t want to sound rude, if Facebook were really concerned about XSS holes in applications, why not look for them in-house? I think the Month of Facebook Bugs report demonstrated how common such issues are, and that was mostly from me spending a few hours poking around various popular apps.

Cross-site scripting issues are a problem in any application. But when they occur in a Facebook application, they compromise Facebook itself in a very real sense. Yet if the Month of Facebook Bugs is any indication, XSS is widespread on the Facebook Platform. And while I noted in September that applications may include vulnerabilities besides the ones I posted, this second hack of Photos I Love gives firsthand evidence.

All of these issues lead me to conclude that Facebook values public sharing and advertising dollars more than users who want to communicate more privately. The content you post and the actions you take on Facebook are at times more easily accessible to applications, advertisers, and injected code than to your own friends. Perhaps those who want to broadcast publicly or use free social games are fine with such an arrangement. But it’s certainly not the Facebook I signed up for.

Facebook StumbleUpon Digg Twitter Instapaper FriendFeed Delicious Google Bookmarks Share/Bookmark

Facebook Knows What You Did Last Summer

Pardon the creative title. In working on accessing Facebook photo albums lately, I noticed that one of the stories on Mark Zuckerberg’s privacy settings mentioned that he’d removed his events from his profile. After finding a way to view public photo albums, I wondered if I could find a way to pull up a user’s public events. That pursuit taught me a little more about Facebook’s privacy settings, and also raised another aspect of Facebook privacy I’d not previously considered.

At first, I followed the same approach as with photos – I tried to make special requests that imitate what happens when you click on a tab in a user’s profile. Doing so brought up no event information for Mark Zuckerberg, but did for a friend of a friend. It turned out this behavior could actually be controlled by a user’s privacy settings. However, the setting may not be where you’d expect – it’s on your application settings page. Facebook treats their events module as an application, and in the settings for the Events application is a field controlling who can see the application. Setting it to “Only Friends” blocks the trick I was using if you’re not the person’s friend; I’m guessing the same setting for the Photos application would block the bookmarklet I posted.

But while Events does appear in the application settings page, it’s not your average application. I knew that the Facebook API included commands for requesting event data. I loaded up Facebook’s API Test Console, set the method to events.get, and put in a user ID.

What came up surprised me – a complete record of practically every public event that user had been invited to. Note that this was not a friend of mine. I could easily filter by whether they had RSVP’d that they were attending the event.

The list only includes “open events,” (Update: “Closed” events are also visible, just not “secret” events) those that are publicly accessible. But the results reminded me of the controversy over Facebook’s original News Feed – while the feature didn’t expose any new data, it made it much easier to access. I’m guessing most Facebook users do not realize you can pull up a list of all the public events they’ve attended so easily.

Also, any application that a user authorizes also has access to secret events a user has been invited to, since the application operates on behalf of the user.

Seeing years of events come up when I put in my own Facebook ID was a wake-up call for me. I handle event requests routinely, but hadn’t really ever given thought to the fact that Facebook has stored all that information – and makes it accessible to others (for public events) and applications. It’s one more aspect of privacy that Facebook users may want to reconsider.

Facebook StumbleUpon Digg Twitter Instapaper FriendFeed Delicious Google Bookmarks Share/Bookmark

Easily View Hidden Facebook Photo Albums

In a previous post, I noted that Facebook had removed access to photo albums for any user not your friend. Soon after Facebook rolled out new privacy controls, some users noticed that they could view anyone’s photo albums marked visible to “everyone,” most notably a few from Facebook’s founder, Mark Zuckerberg. Soon after those reports, however, it appeared that the albums were no longer available, as “Photos” tabs disappeared from public profiles and visiting photos.php simply gave an error message.

But as I described, access had not been cut off – Facebook had simply made the albums harder to find. This practice, known as security through obscurity, can mislead users who think their hidden content is safe from prying eyes. To prove my point, I gave directions on how to load the public photo albums of any given Facebook user.

Those directions were a bit technical, however, and I wanted to make the point more obvious. After working through more Facebook code, I came up with a bookmarklet (a bit of JavaScript you can store as a bookmark in your browser) for viewing public photo albums. Bookmark this link, or copy the code below. (Tested in recent versions of Opera, Firefox, and Chrome.)

javascript:(function(){function y(){if(x.readyState==4){q=x.responseText.substring(9);p=eval(‘(‘+q+’)’);document.getElementById(‘tab_canvas’).innerHTML=p.payload.tab_content;}}x=window.XMLHttpRequest?new window.XMLHttpRequest:(window.ActiveXObject?new ActiveXObject(“MSXML2.XMLHTTP”):null);x.onreadystatechange=y;x.open(‘POST’,’http://www.facebook.com/ajax/profile/tab.php’,true);x.send(‘id=’+ProfileURIController._profileId+’&v=photos&__a=1′);})()

Once you’ve saved the link, simply visit someone’s public Facebook profile, then load the bookmarklet. It will replace the body of the user’s profile with a list of links to public albums, if any are available. The results are not formatted well, and only include the first page of albums, but the code works enough to at least demonstrate that public albums are not as well-hidden as you might expect.

I’ve browsed through some random profiles, as well as some more prominent Facebook users, and I think many would be surprised by how many photos I was able to access through this trick. Note that this code does not circumvent privacy settings in any way – it simply makes visible albums you can rightfully access but that Facebook has hidden from view otherwise.

At some point, users who have followed default album settings in the past and left many photos accessible to “everyone” are in for a shock when they realize the implications of those choices. I personally think it best for them to realize that now instead of later, which is why I decided to release this technique.

Facebook StumbleUpon Digg Twitter Instapaper FriendFeed Delicious Google Bookmarks Share/Bookmark

1 3 4 5 6 7 15