So one of the problems with security in code writing is that although the user interface only lists specific options for drop down fields, etc. the server code may not be verifying that the form data actually sent back by the user indeed falls within the specifications. In other words, the server sends the client a web page saying, "Do you choose A, B, C, D or E?" but it actually will accept F as input well! This is bad practice and in some cases can be a serious vulnerability.
Today's hack involves Facebook, so that's fun. Our hack will send back data to the Facebook server that the webpage was not intended to send but we aren't going to hack anybody's account or anything, so don't get too excited.
The hack comes from mad PHP super ninja Steven Corbett of
motionmods.com who is my good buddy. Steven has figured out a way to hack Facebook's Timeline so that so called Life Events can be generated as having occured in the future.
First, I'll give you the hack, then we'll interview Steven for more detail on the hack and what can be done to prevent it.
What you'll need for the hack:
- Timeline enabled on your Facebook profile
- Google Chrome (Firefox could work, too, but the instructions below are for Chrome.) I'm using Windows 7 today, fyi.
Okay, so here's the hack:
1. Browse to your Facebook profile and choose Life Event
2. You'll have varying levels of hacking success with different Life Events, but for the moment we'll choose Travel & Experiences...>Tattoo or Piercing...
3. You'll notice that the When drop-down only goes up to the current year (2012). We'll modify things so that we can go to a higher year. We can go up to 2037 for this hack. As to why 2037, um maybe it has something to do with
this? To modify the year, RIGHT click on the drop down and choose Inspect element.
4. In the elements pane, expand the following line which is highlighted automatically by clicking the little arrow on the left:
<select data-name="year" class="periodMenu yearMenu" name="date_start[year]">
5. Find the line below and change the option value from 2012 to a year in the future up until 2037:
<option value="2012" selected="1">2012</option>
6. Fill in the Story field, click the drop down next to the Save button for your privacy level and then click Save. Clicking Save may not appear to do anything because for whatever reason the hack freaks it out and the window doesn't close, but if you check your timeline it does save properly. Yay.
Here's a video of me doing the hack. I've got a very small screenshot size set intentionally in order to maintain some level of privacy on my Facebook. The good news though is that this video is much better quality than my last one!
So what can a developer do to protect against this? Let's ask mad PHP super ninja Steven Corbett of
motionmods.com...Below is an interview I did with Steven...
James: Nice work on the Facebook timeline hack, Steven. When I saw your Timeline posts in the future in my feed I immediately wanted to know how you did this. What inspired this? A little too much coffee and a desire to break stuff? Tell us about your inner hacker self.
Steven: The coffee probably did have something to do with it, but I had run into an issue with a couple of clients where they were having weird, spammy content posted through the forms on their sites. Or so we thought. Funny thing was, some of the values coming through weren't even options in the forms. As it turned out, they were being posted from remote servers using cURL, so the options on the forms were bypassed and completely irrelevant- these spammers were submitting whatever their despicable hearts desired!
Anyway, it got me wondering how Facebook handled unexpected values in user input, so on a whim I gave it a whirl, and was pretty surprised to see that sometimes they don't! :)
James: Okay so I'm not a developer...help me out here. So when we are using Inspect element to edit the code, we're basically saying to the server: "Thanks for the webpage you sent to our browser but we're gonna manipulate your webpage with new capabilities to send you back stuff you didn't expect" ...right? Can you elaborate?
Steven: Pretty much! The server sends you the page that it wants you to see, with the features and options that it thinks you should have, but if you feel that you deserve more, you can tweak it to suit using something like Dev Tools in Chrome/Chromium, or Firebug in Firefox. Even IE can do this stuff now, if you're ok with looking like Grandma (and if you don't mind the extra 13 steps required for each action).
I used to leave notes for my wife on Google's home page this way...and once or twice spoofed a cold, heartless message from a trusted friend on someone's FB wall when they left it open. :)
James: Fun! So what can developers do to protect their server code from allowing unexpected input? Could you give us some generic example server side code?
Steven: With all the buzz around javascript/jQuery form validation, it's way too easy to forget that anything coming from the client-side can be manipulated and can't be trusted. Server-side validation may be boring, but it's essential!
Here's an oversimplified PHP example of something Facebook could do in this particular scenario:
$year=(int)$_POST['year'];
$month=(int)$_POST['month'];
$day=(int)$_POST['day'];
$current_time=time();
$submitted_time=strtotime("$year-$month-$day");
$proceed=($submitted_time>$current_time?false:true);
This takes the input, makes sure that the values are integers (since that's what Facebook is using), then converts them to a timestamp which can be checked against the current timestamp to ensure that the value is within what was expected.
James: Great! Well, thanks for the hack, Steven. Hey, tell us a bit about what you do at motionmods.com...
Steven: Hmm...besides pretending to be an expert on a media CMS that no one knows anything about, I custom build PHPmotion-based video sites. More often than not I end up breaking stuff majorly, but it's fun anyway, and I get to stay home all day and call it a job.
Awesome! Thanks again, Steven and happy hacking!
Steven: Thank you! :)