Vulnerable register_globals

You should exercise extreme care when working with parameters. If the register_globals parameters is set to On in the php.ini configuration file, global variables are created. This can be a vulnerability source if you are not being careful enough. Let's consider the following vulnerability demonstration example:

<form action="testpass.php" method="get">
 Login: <input name="username">
 Password: <input name="password">
</form>

if ($password== $legal_pass) and ($username==$legal_name)
  $logged = 1

if ($logged)
 {
  //The user has been authorized
 }

The example's logic is quite simple. The testpass.php script is passed two parameters: $username and $password. If they pass the validity check, the $logged variable is set to 1. Next, the value of the $logged variable is tested: If it is equal to 1, the authorization is successful and the user is granted access to whatever the script is supposed to run.

The URL string that is supposed to be used in this example looks as the following:

http://192.168.77.1/testpass.php?username=admin&password=pass

But what will happen if a hacker adds the logged parameter to this URL?

http://192.168.77.1/testpass.php?username=admin&password=pass&logged=1

True, this parameter is not sent from the form, but this circumstance does not mean that we cannot do this manually. You can send any parameter in the URL, even such that is not used in the script, and the PHP interpreter must create this variable.

In our example, before the script is started, the interpreter creates a variable $logged and sets it to 1. Now, it does not matter if the name and password check is negative because the check for $logged being set to 1 will be positive anyway, and the hacker will be granted access.

At glance, it may seem that it is quite easy to crack the script using parameters passed to it. But to do this the hacker must have access to the script's source code in order to know the variables used in the script. If the script's source code is protected, it is practically impossible to guess the parameters it uses. But if your script is of the Open Source type, you may have problems.

These can be addressed in the following two ways:

1. Set the register_globals directive to off and use the arrays. In this case the value of the $logged variable provided by the script and that provided by the array will be different, and it will be impossible to carry out a break-in in this way.

2. Initialize variables that are not supplied by the user. I prefer this way, because I don't want to give up on global variables, while variable initialization allows effective protection. Variables must always be initialized at the very beginning of the script.

The following code shows how initializing variables prevents using them to crack a script.

<form action="testpass.php" method="get">
 Имя: <input name="username">
 Пароль: <input name="password">
</form>

$logged=0; 
if ($password== $legal_pass) and ($username==$legal_name)
  $logged = 1

if ($logged)
 {
  //The user has been authorized
 }

Now even if the $logged variable is faked, at the start of the script it is set to 0, and only a successful user name and password check will set to 1.

The PHP developers decided not to put their trust into professionalism of web programmers and set the default value of the register_globals directive to off. If you are certain that all your variables have been initialized, you can set this directive to on.

Tag: PHP Development | Date:1/18/2010 9:12:15 PM