I don’t know if any of you have kept up on the recent problem Facebook is facing, but it’s actually a fairly interesting topic. For those of you who haven’t followed, basically what happened was some of the PHP code used to power their website, was accidentally leaked to the public, and someone decided to post it on their blog for everyone to see. I actually managed to have this happen to me directly, when using Facebook on Thursday, and I made a copy in notepad with the hopes of checking it out down the line, for curiosity’s sake. Since then, however, the whole issue has ballooned into something big, pretty much overnight, with people challenging Facebook’s ability to keep user data private and questioning whether anyone’s details are actually safe.
For the most part, I think most web developers are somewhat lazy when it comes to security for their sites, especially bloggers. This is especially true whenever someone is using a free open source content management system (CMS) like WordPress because they figure there is nothing worth protecting anyway. This is a dangerous viewpoint to take because even with a system like WordPress, there is a lot of data you wouldn’t want the public gaining access to. For example, your config file containing your database username and password or your customized theme directory containing everything a person needs to copy your site layout.
While the problem at Facebook has been officially clarified as an apache/mod_php bug, there are only a few things that could have caused the problem. Either it was an accident and someone didn’t shut off some output code, it was malicious, or there was a problem with mod_php processing the file which caused it to be displayed as plain text. Facebook says:
“Some of Facebook’s source code was exposed to a small number of users due to a bug on a single server that was misconfigured and then fixed immediately. It was not a security breach and did not compromise user data in any way. The reprinting of this code violates several laws and we ask that people not distribute it further.” It seems that the cause was apache and mod_php sending back un-interpreted source code as opposed to output, due to either a server misconfiguration or high load (this is a known issue). It is also apparent that other pages have been revealed, and that this problem has occured before, but only now has somebody actually posted the code online.
Here are some general tips you can apply to your own site and web server to prevent the same thing from happening to you:
Always, ALWAYS, test your code first before uploading it to your web server. I know I’m guilty of this, and so are a lot of us. When you’re in a rush, and you just need to make a few quick tweaks to your site, it’s easy to quickly connect with Dreamweaver (or another code editing package) and make the changes directly on your live site. You should always maintain a local installed version of your sites where all modifications are made. This way you can test them out in a closed environment, and update your public site once you’re sure the changes are implemented correctly. Installing a local version of PHP, Apache, and MySQL is getting easier all the time and with tools like WAMP available, so there is almost no excuse not to have a local install. If you absolutely can’t run a local version, you can always setup a “test” version on your web server that is password protected on an unknown URL.
Enhance the security of your site using .htaccess. There are simple additions you can make to your .htaccess file that will make it more difficult for people to “accidentally” gain access to your code. In the event that mod_php is unavailable, or fails to load, you can take steps to ensure your php files won’t be displayed as plain text. Simply add some code such as the following to your .htaccess file (making sure to adapt it slightly depending on your mod_php version):
Deny from all
Allow from none
What this code will do is prevent access to any file ending in .php in the event that mod_php is unavailable.
Modify your default file type for unknown files. This is one of the simplest changes you can make to your configuration, that takes almost no effort and really shouldn’t effect the way most of you currently run your site. In your .htaccess file, you can simply add the line:
DefaultType application/<any application type>.
You can pretty much use any application type you want. All this does is tell your web server to interpret any file extension it doesn’t recognize as something other than a text file. By default, apache assumes everything it doesn’t recognize is a text/plain type, so in the event that PHP is not being processed correctly, it will return your files as plain text. Try out a few different application types until you find one that works right for your site.
Try and keep as many of your files as possible outside of web accessible directories. This is not always an option, for packages like WordPress, but for any of us writing our own sites from scratch, this is a simple measure that can help protect your private data. In PHP, all data files are added to your site using include statements. For example, if I want to get at a configuration file I have containing database access information like usernames and passwords, I might do something like:
<?php include( ‘config.php’ ); ?>
If config.php is located inside the root of my web folder (i.e.. anywhere under the www or public_html folder on most apache installs) then technically it is accessible via the web. The only thing that prevents people from being able to see the contents is that you have mod_php installed, which tells your server to interpret all .php files as code to process and not plain text. You could easily protect yourself further by moving config.php outside of the web root:
<?php include( ‘<path to inaccessible directory>/config.php’ ); ?>
The less you have stored in your web root, the less opportunities there are for public visitors to access your private data files. For a site like Facebook, where you have full control over the placement of all files (because you designed it yourself), you can setup almost any structure you want moving most private data files outside of the root folder.
Limit your code access list to trustworthy partners. This seems like a DUH point, but I think it bares mentioning anyway. The best way to prevent malicious code leaks or even accidental code leaks is to limit the number of people with access to your code. On several projects I’ve worked on, we’ve had large teams that included business managers, CEO’s, software engineers, graphic designers, database guys, marketing teams, etc etc. On one project in particular, it was considered “bad form” to prevent any of those people from accessing the source code. At the time I was just software engineer 1 of 20, but I bet you can guess what happened next. One of the business guys decided to “get his feet wet” with the programming aspects of the site and ended up showing off a ton of features that were not ready for release, giving our competitors a leg up. At the end of the day, transparency is key to good synergy within a team, but very few people need access to the live builds of sites and software, and the less people who do, the better.
These are just a few suggestions you can readily implement to help protect your site from a similar PHP leak. It’s always a good habit to get into a security based mind set when it comes to working with the web. This is much more crucial when it comes to designing your own systems for your projects, where the onus of protection is on you entirely. Keep in mind that if you are using a decent web host, many of these changes may have already been made for you on a server-wide level. Nonetheless, it is better to be safe than sorry, so always check first and make sure things are locked up tight. Anyone else have any suggestions for ways in which to improve your security from file leakage?
Update: Nik Cubrilovic, the original reporter on Tech Crunch, has posted his own set of tips on how to ensure your site is leak proof. His article was posted after I finished my first draft on this article, but it contains a few additional tips, and some interesting comments as well, on how to keep your site as secure as possible. Nik Cubrilovic recommends using application/x-httpd-php as a type for the default file type solution. I thought this was a pretty good idea, as it will force your web server to treat anything it doesn’t recognize, as if it was a php document needing to be processed by the PHP interpreter. You can still experiment with different types, and almost all of them will give you the same desired outcome…protected php files.