Friday, May 07, 2010

What Facebook’s recent bug tells us

I was listening to latest TWIG when I heard that Facebook recently had a security breach. They explained that Facebook has a feature allowing to mimic a friend’s login for viewing on your profile by the eyes of that friend (“With Preview My Profile, users can view how their profile appears to any given Facebook friend”). And it happens that that friend’s login were almost real, allowing to see the live chats and friend requests of the friend in question.

OK, security breaches happen. They are discovered and then fixed. But what this particular case tells us about Facebook platform? I suspect, it tells a lot of negative and alarming things. Let me explain.

We have a similar feature in our Corporate Intranet written in a mix of classic ASP and ASP.NET. We call it Super User (SU) login. SU allows for selected administrators to login into Intranet as a different employee to debug some issues. In fact, SU login matches a regular login by 99%. One per cent of difference is that there is a special set of private user’s data which is visible only to user himself or to a user and strictly defined group of people, for example HR. In case an admin who uses SU is not in HR group, employee’s private data is not visible through SU login.

A several years ago security breaches like one which happened to Facebook was pretty common for us too. But now we virtually eliminated their possibility.
We use a regular ASP feature to store in memory current user’s identity – a Session variable. When SU login happens, user’s Session variable is actually reset to identity of user being SUed. It allows to fully mimic other user’s experience. In SU login, a second Session variable is set, keeping original user’s identity and indicating that we are in SU mode. When it comes to seeing some restricted private user’s data, code checks if user has permissions to see it and, if we are in SU mode, if actual user has rights to see it as well.

A real question is how system determines permissions (rights) of a particular user. Normally, Rights are attached either to user himself, or to Roles that user share. Initially, our Intranet used a bunch of ‘If’ statements in ASP code. If a user is HR, this is allowed on this page. If a user is DBA, he can do this and this. If you have a developer experience, it should be absolutely clear to you that such a system is very fragile and inconsistent. To break it, It’s enough to add a new page and forget some ‘If’ statement, it’s enough to modify Rights of a particular Role and forget to modify ‘Ifs’ on one page. It even much easier to add a new page and forget that you need to check not only rights of a current user, but also, in case it’s a SU login, rights of original user.
So, a system described above is really amateurish, fragile, hard to maintain, and no-professional.

Now you probably understand what I’m thinking about Facebook? As a web developer with 15 years of experience, I have a strong feeling, that Facebook, which had a bunch of developers of different levels, which grew up from a small system written in PHP for college students, suffers from the same inconsistent code, uses hard-coded ‘If’ statements to determine user’s rights and to mimic another user’s experience in “Preview My Profile”. This assumed amateurish inconsistent system in combination of its Facebook Über Alles syndrome looks especially dangerous and incapable of keeping users privacy.

Finally, a system managing users permissions looks as a relational structure in its essence. Basically, there should be tRight table, tRole table, and tRightOfRole link table (many-to-many relationships). It’s a bit more complex if Rights are assignable not only to Roles, but to individual Users as well. It gets some additional complexity if Role-Right combinations are different for different pages or sections of your system (web site). We introduced a notion of Scope. Both Roles and Rights are defined either globally or on a particular Scope within a system. Role-Right combination is to be assigned on a Scope too. A resulting relational system is extremely powerful and flexible, much more flexible than any system written based on Active Directory groups, like MS SharePoint (We tried to use MOSS 2007 and found it not flexible enough to accommodate for business rules).
And yes, we actually wrote such a relational system, called Roles Rights Management (RRM). Besides relational structure I described above, it uses some clever techniques and HttpModules, which allowed us to automate its usage. It is not a responsibility of particular programmer anymore, to properly check user’s permissions to allow/disallow viewing a page or to filter data. In most case, Security Trimming happens automatically.
That’s what I think Facebook programmers failed to implement.