Friday, February 25, 2011

Simple way to do a facebook like check in java


People are making this so hard.  Now facebook is moving from fbml you gotta do the like check yourself instead of using the very convenient . Here is my simple solution after 3 hours of trying the hard versions.

static final Pattern FB_SIGNED_REQUEST_PATTERN = Pattern.compile("liked\":(.)");
static final BASE64Decoder BASE64_DECODER = new BASE64Decoder();
public static boolean isFacebookFan(HttpServletRequest request)
throws Exception
{
String fbreq = request.getParameter("signed_request");
if (fbreq == null) throw new Exception("No request");
fbreq = new String(BASE64_DECODER.decodeBuffer(fbreq));
log.error(fbreq);
Matcher m = FB_SIGNED_REQUEST_PATTERN.matcher(fbreq);
return m.find() && m.group(1).equals("t");
}

Tuesday, January 11, 2011

The Firesheep Problem, and How rcwilley.com Is Protected

Recently with the new "Firesheep" firefox addon that steals facebook and twitter sessions over unsecured wifi sidejacking is in the news.  I thought I'd sit down and write about my solution to the problem which protects rcwilley.com sessions from being hacked.

A few years ago when I changed jobs into the web engineering business I was forced to get up to speed on session cookies and how they are used.   For those of you not familiar with how cookies work here is a quicks simplified primer:

Cookies are little pieces of data that a website can send to your browser.   Then whenever your browser communicates with the same server it got the cookie from, it sends it in the request.   The web server can then look at this cookie and know what browser he is talking with.  When you log into a website, it is very common for them to send a piece of data called a session cookie to your browser.  Then every time you ask for a new page they know who you are.   Now this is all perfectly secure and safe as long as you never communicate with the server over a non-secure http connection.  However most websites, after using a secure https connection to send your login and password over, switch back to http for performance.  They don't pass your password any more, but every request from your browser has the session cookie sent UNPROTECTED to the server.  That is how the server knows who you are for the rest of your visit.

Now there is a concept of a secure cookie which the browser is only allowed to send over a secure https connection, but they are hardly ever used.  This is because the user may make a request over http all of a sudden, and the server won't know who it is.

One of my first tasks was to create a single sign on kind of solution that allowed customers to log into our site and stay logged in while they moved between normal and secure pages on our site.   I got it working the commonly accepted way of using the session cookie to maintain the users login credentials throughout their visit.  This worked just fine, but I wanted to make sure my solution was secure when we switched between http and https.

After hunting around on the internet on ways to hack sessions I learned about sidejacking.  This is when someone able to watch network traffic between a browser and the web server just grabs a session cookie and uses it to pretend to be someone else.  I asked one of the top engineers at my web consultant firm how to prevent this, and he said I shouldn't worry about it because it was to hard to do a sidejack of a cookie, and no one else worried about it.  I visited many big websites, and watched their cookie usage. None of them used secure cookies.  Facebook and twitter were common examples of these kind of sites, so it seemed that my co-worker was right about sidejacking being a non-issue.

Basically web sites seem to be in the following camps:

1. Sites that are stateless and need no cookies
2. Sites that use https for login, but no secure cookie, risking an http connection sending the cookie in the open.  These are the risky ones like facebook and twitter.
3. Sites like 2  that fortunately make you login again every time you go into a secure area.  This helps.
4. Sites like 2 that make you login every time you enter a secure area, and then use a secure cookie.  Amazon appears to be in this camp.
5. Sites that are completely https and use secure cookies and suffer the performance penalties.  Mostly banks and the like.

My favorite kind of site is 2 because it doesn't irritate the user after they already logged in, but it is too risky.  I still just didn't feel right about being a type 2 site.  So for rcwilley.com I adopted a combination solution that would give me the benefits without the problems.   The simple solution is to use both secure and normal cookies, and require the secure cookie whenever the user re-enters a secure area.  It was very easy to implement and completely solves the problem as far as I can figure.   Twitter and Facebook ought to consider this method if they don't want to go completely secure like a bank.

Now some nitty gritty details for those who care.  When the user logs in, I do it over a secure request and I give them their normal session key in a normal cookie.  I don't have to mess with the default behavior of tomcat at all.  At the same time I also generate a secure cookie and send that as well.  The secure cookie value is simply stored in their session with everything else.  Thereafter they can go to an http section of the site, and back without having to re-login.   Whenever they try to make a secure request from then on I just check to make sure they also sent me the correct secure cookie as well.  Otherwise they have to log in again.  Works like a charm.