Recently I was asked to take a peek at a content management system currently in developement. A lot of it seemed relatively stable, except for this one short snippet of code. Whenever a protected page is loaded, one that you have to be logged in to view, a function containing this code is called:
if(!isset($_SESSION['session']["privLvl"])) {
header("Location: login.php");
}
It grabs a variable called 'privLvl' registered to the users session. If the user is not logged in, this variable is unset and the browser is redirected to the login page. So then, what is the problem? The problem exists, because our developer is putting his trust in a function that depends on the browsers response. header("Location: login.php"); will force a browser to redirect to login.php, but only because that is how a browser is programmed to react. watch what happens when I load this page in ie, then in netcat:
first, here is the code for admin.php:
<?
if(!isset($_SESSION['session']["privLvl"])) {
header("Location: login.php");
}
echo "BIG SECRET!";
?>
Here is an image of what loads in IE:
that form is what is stored in login.php, we've been happily redirected, as intended. And now, in netcat:
Whoops. Netcat has no idea what to do with the Location: header, its not a browser. A secure way to implement this would be as follows:
<?
if(!isset($_SESSION['session']["privLvl"])) {
header("Location: login.php");
exit();
}
echo "BIG SECRET!";
?>
Here we force exit of the script after redirect, incase the client doesn't listen.
There are plenty of other vulnerabilities based on this same flawed thinking. Using javascript to sanatize input is a common one. As a developer you should always be concious of what your functions depend on, and whether or not those dependencies are under your control.