Write a safe script with PHP 4.2!

xiaoxiao2021-03-06  39

Original: Kevin Yang

For a long time, the PHP as one of the biggest selling points of the server-side scripting language will automatically establish a global variable for the value submitted from the form. In PHP 4.1, PHP producers have recommended an alternative to submitting data. In PHP 4.2, they canceled the old approach! As I explained in this article, the purpose of making such changes is for safety considerations. We will study new practices for PHP in handling form submission and other data, and explain why this will increase the security of the code.

What is wrong here?

Take a look at the PHP scripts below, it is used to authorize access to a web page when the username and password is correct:

// Check the username and password

IF ($ usrname == 'kevin' and $ password == 'secret')

$ authorized = true;

?>

please enter your username and password:

username:

Password:

OK, I believe that about half of readers will say "too stupid - I will not make such mistakes!" But I promise that there are a lot of readers will think "Hey, there is no problem, I will write this." "Of course, there will be a few people who are confused about this problem (" What is PHP? "). PHP is designed as a "good and easy" scripting language, beginners can learn to use it in a short period of time; it should also be able to avoid beginners to make the mistakes.

Go back to the question just now, the problem in the above code is that you can easily access the power, without providing the correct username and password. Just add the last addition of the address bar of your browser? Authorized = 1. Because PHP will automatically create a variable for each submitted value - whether it is from a submitted form, the URL query string is still a cookie - this will set the $ authorized to 1, such an unauthorized user Can break the safety limit.

So how do you simply solve this problem? As long as the $ authorized default is set to false at the beginning of the program. This problem doesn't exist! $ authorized is a variable created in the program code; but why developers worried about the variables submitted by each malicious user?

What changes do PHP 4.2?

In PHP 4.2, the register_global order in the newly installed PHP defaults to shut down, so the EGPCS value (EGPCS is an abbreviation of Environment, GET, POST, COOKIES, Server - this is the full range of external variable sources in PHP) Will not be It is created as a global variable. Of course, this option can also be turned on by manual, but PHP developers recommend you to close it. To implement their intentions, you need to use other methods to get these values. Starting with PHP 4.1, the EGPCS value can be obtained from a set of specified arrays:

$ _ENV - contains system environment variables

$ _GET - Contains variables in the query string, and the variables in the form of the form

$ _POST - Contains variables in a form for POST

$ _COOKIE - contains all cookie variables

$ _SERVER - Contains server variables, such as http_user_agent

$ _REQUEST - contains all the contents of $ _GET, $ _ POST and $ _COOKIE

$ _SESSION - contains all registered session variables

Before PHP 4.1, when the developer turns off the Register_GlobalS option (this is also considered to improve a method of improving PHP performance), you must use the annoying names such as $ http_get_vars to get these variables. These new variable names are not just short, and they have other advantages.

First, let's override the code mentioned above in PHP 4.2 (that is, turning off the register_global option):

$ username = $ _REQUEST ['username ";

$ Password = $ _REQUEST ['Password'];

/ / Check the username and password

IF ($ usrname == 'kevin' and $ password == 'secret')

$ authorized = true;

?>

please enter your username and password:

username:

Password:

As you can see, what I need to do is just the beginning of the code at the beginning of the code:

$ username = $ _REQUEST ['username ";

$ Password = $ _REQUEST ['Password'];

Because we want the username and password being submitted by the user, we get these values ​​from the $ _REQUEST array. Using this array allows users to freely select delivery: through the URL query string (for example, automatically enter their certificates when creating bookmarks), through a submitted form or through a cookie. If you want to restrict, you can only submit a certificate through a form (more accurately, you can use $ _POST arrays: $ usrname = $ _POST ['username "];

$ Password = $ _POST ['Password'];

Except for "introducing" these two variables, the program code does not change any changes. Simply shut down the register_globals options to make developers further understand which data is from external (untrusted) resources.

Please note that there is still a small problem: default error_reporting settings in PHP is still e_all & ~ e_notice, so if "username" and "password" are not submitted, try to get from the $ _REQUEST array or $ _POST array These two values ​​do not incur any error messages. Such as the PHP program is not your PHP program, you need to add some code to first check these variables.

But does this mean more input?

Yes, in a simple program like the above, using PHP 4.2 often increases the input. But still look at the bright side of the light - your program is more secure!

But seriously, PHP's designers did not completely ignore your pain. In these new arrays, there is a special feature of other PHP variables, which are complete global variables. What help does this help? Let us first expand our example.

In order to make multiple pages in the site can use the username / password argument, we write our user authentication program to a ProtectMe.php:

Function Authorize_User ($ Author, $ Authpass)

{

$ username = $ _POST ['username'];

$ Password = $ _POST ['Password'];

/ / Check the username and password

IF ($ usrname! = $ authuser or $ password! = $ authpass):

?>

please enter your username and password:

username:

Password:

exit ();

Endif;

}

?>

Now, our page will look like this:

Require ('Protectme.php');

Authorize_user ('Kevin', 'Secret');?>

Very simple, very clear, right? Now is the time to test your eyesight and experience - what did you have in the Authorize_user function?

There is no declaration in the function $ _POST is a global variable! In PHP 4.0, when register_global is turned on, you need to add a line of code to get $ username and $ password variables in the function:

Function Authorize_User ($ Author, $ Authpass)

{

Global $ UserName, $ Password;

...

In PHP, and other languages ​​with similar grammar, the variables outside the function cannot be automatically obtained in the function, and you need to add a row as you described above to specify its from the Global range.

In PHP 4.0, when the register_global is turned off to provide security, you can use the $ http_post_vars array to get the value submitted by your form, but you still need to import this array from the global scope:

Function Authorize_User ($ Author, $ Authpass)

{

GLOBAL $ http_post_vars;

$ username = $ http_post_vars ['username'];

$ Password = $ http_post_vars ['password'];

However, in PHP 4.1 and later, special $ _POST variables (and other variables mentioned above) can be used within all ranges. This is why no need to declare $ _POST variable in a function:

Function Authorize_User ($ Author, $ Authpass)

{

$ username = $ _POST ['username'];

$ Password = $ _POST ['Password'];

What is this impact on session?

The introduction of special $ _SESSION arrays actually helps to simplify the session code. You don't need to declare the session variable as a global variable, and then pay attention to which variables are registered, you can now quote all your session variables from $ _SESSION ['VarName'].

Let us now take a look at another example of another user authentication. This time, we use sessions to margin a user who continues to stay in your website has passed user authentication. First, let's take a look at the PHP 4.0 version (open register_global):

session_start ();

IF ($ usrname == 'kevin' and $ password == 'secret')

{

$ authorized = true;

Session_register ('authorized');

}

?>

Like the procedures that have just started, this program also has security vulnerabilities, plus the last plus of the URL? Authorized = 1 can bypass the security measures directly to access the page content. Developers can treat $ authorized as a session variable and ignore the same variables that can be easily entered via the user input. When we add our special array (PHP 4.1) and turn off register_global (PHP 4.2), our program will be like this:

session_start ();

IF ($ usrname == 'kevin' and $ password == 'secret')

$ _SESSION ['Authorized'] = True;

?>

Is it even more simple? You no longer need to register the normal variable as a session variable, you only need to set the session variable directly (in the $ _SESSION array), then use it with the same method. The program becomes shorter, and it will not cause confusion for what variable is session!

to sum up

In this article, I explained the deep cause of the PHP scripting language to make changes. In PHP 4.1, a set of special data is added to access external data. These arrays can be called within any range, which makes access to external data more convenient. In PHP 4.2, Register_Global is closed by default to encourage these arrays to avoid unsafe PHP code.

转载请注明原文地址:https://www.9cbs.com/read-69776.html

New Post(0)