PHPsu
MANUAL ZH  |  EN
     


Current Position :| index>Beginners> PHP security rules

PHP security rules

FROM: AUTHOR: TIME:2008-06-03 HITS:
Rule 1: Never trust external data or enter

On the Web application security, we must recognize that the first thing should not be trusted external data. The external (outside data) is not included in the PHP code by the programmer in the direct input of any data. In taking measures to ensure security before, from any other source (such as GET variables, form POST, databases, profiles, session variables or cookie) of any data are not trusted.

For example, the following data elements can be considered safe, because they are in PHP settings.

List 1.'s No time security code

<?php
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);
?> www.phpsu.com

However, the following data elements are flawed.

List 2. Insecurity, the flawed code

<?php
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!
?>

phpsu.com

Why is the first variable $ myUsername is flawed » Because it directly from the form POST. Users can input in this field to enter any string, including the removal of documents or to upload the file before running the malicious commands. You might ask, "Do not use only letters AZ client (Javascrīpt) test script form to avoid this danger?» "Yes, this is always a good step, but, as will be seen in the back , Any person of any form can be downloaded to your machine, edit it, then they need to re-submit any of the contents.

Solution is simple: the need for $ _ POST [ 'username'] clean-up operation code. If we do not do this, then the use of $ myUsername any other time (for example, in an array or constants), these objects may be contaminated.

The user input for cleaning up a simple method is to use regular expressions to deal with it. In this example, accept only hope that the letters. Will be restricted to a specific number of the string of characters, or requirements are all lowercase letters, which may also be a good idea.
www.phpsu.com


List 3. User input to become security

<?php
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!
function cleanInput($input){
    $clean = strtolower($input);
    $clean = preg_replace("/[^a-z]/", "", $clean);
    $clean = substr($clean,0,12);
    return $clean;
}
?>

www.phpsu.com

Rule 2: disable those that will be difficult to implement safety of the PHP settings

Are aware of can not trust user input, it should also be aware that the machine should not trust your PHP way. For example, to ensure that disabled register_globals. If you enable register_globals, can do some careless things, such as the use of $ variable replacement of the same name GET or POST string. By disabling this setting, PHP forced you to the correct name in the space under the correct variables. To use the form from POST variables, we should use $ _ POST [ 'variable']. This will not be misunderstood as this particular variable cookie, conversation or GET variables.

Rule 3: If it can not understand, we can not protect it

Some developers use strange syntax, or organizations will be very compact statement, a brief but vague code. This may be efficient, but if you do not understand the code is doing what, then will not be able to decide how to protect it. do you kown phpsu.com?

For example, you like the following two pieces of code in which section »

List 4. Code easier to be protected

<?php
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');
//unobfuscated code
$input = '';
if (isset($_POST['username'])){
    $input = $_POST['username'];
}else{
    $input = '';
}
?>

phpsu.com is a free phpscool

Relatively clear in the second paragraph of the code, it is easy to see that $ input is flawed, the need for clean-up before they can safely handle.

Rule 4: "defense in depth" is the new magic weapon

This handbook will use an example to illustrate how to protect the online form, in the form of PHP code dealing with the use of the necessary measures. Similarly, even if the use of PHP regex to ensure that GET is the number of variables, can still take measures to ensure that the use of SQL query escaped the user input.

Defense in depth is not just a good idea, it can ensure that you will not be in serious trouble.

As already discussed the basic rules, now the first to study a threat: SQL injection attacks.

Prevent SQL injection attacks

In SQL injection attack, the user through the manipulation of form or GET query string, the information will be added to the database query. For example, if a simple sign in the database. This database has a record of each user name, and a password field. Construction of a login form that allow users to log. do you kown phpsu.com?

5 list. Simple login form

<html>
<head>
<title>Login</title>
</head>
<body>
<form action="verify.php" method="post">
<p><label for='user'>Username</label>
<input type='text' name='user' id='user'/>
</p>
<p><label for='pw'>Password</label>
<input type='password' name='pw' id='pw'/>
</p>
<p><input type='submit' value='login'/></p>
</form>
</body>
</html> phpsu提供的php教程

To accept this form of user input user name and password and user input submitted to the paper called verify.php. In this document, PHP processing of data from the login form, as follows:

6 list. Unsafe handling of the PHP code form

<?php
$okay = 0;
$username = $_POST['user'];
$pw = $_POST['pw'];
$sql = "select count(*) as ctr from users where username='".$username."' and password='". $pw."' limit 1";
$result = mysql_query($sql);
while ($data = mysql_fetch_object($result)){
    if ($data->ctr == 1){
        //they're okay to enter the application!
        $okay = 1;
    }
}
if ($okay){
    $_SESSION['loginokay'] = true;
    header("index.php");
}else{
    header("login.php");
}
?> phpsu.com is a free phpscool

This code looks no problem, right » The rest of the world hundreds (or even thousands) of the PHP / MySQL sites are in the use of such a code. Where goes wrong it » Well, remember that "can not be trusted user input." There is no right of any information from the users to escape, so the application vulnerable to attack. Specifically, there may be any type of SQL injection attacks.

For example, if a user enters foo as a user name, enter 'or'1' ='1 as a password, then in fact will be the following string passed to the PHP, and then passed to the query MySQL:

<?php
$sql = "select count(*) as ctr  from users where username='foo' and password='' or '1'='1' limit 1";
?>

do you kown phpsu.com?

he query is always the return of value of 1, PHP will be allowed to visit. By the end of the string password into some malicious SQL, hackers will be able to dress as legitimate users.

Solution to the problem is that PHP's built-in mysql_real_escape_string () function for any user to enter the wrapper. This function of the string of characters escaped, it is impossible to string transmission charge-offs and other special characters, and MySQL to operate under the special characters. List of seven escaped with a display of handling the code.

List 7. PHP form handling the security code

<?php
$okay = 0;
$username = $_POST['user'];
$pw = $_POST['pw'];
$sql = "select count(*) as ctr from users where username='".mysql_real_escape_string($username)."' and password='". mysql_real_escape_string($pw)."' limit 1";
$result = mysql_query($sql);
while ($data = mysql_fetch_object($result)){
    if ($data->ctr == 1){ www.phpsu.com
        //they're okay to enter the application!
        $okay = 1;
    }
}
if ($okay){
    $_SESSION['loginokay'] = true;
    header("index.php");
}else{
    header("login.php");
}
?>

http://www.phpsu.com

Use mysql_real_escape_string () as a user enters the packaging, user input could be avoided in any malicious SQL injection. If users try to pass through the SQL injection deformity password, then will be transmitted to the database for the following:
http://www.phpsu.com

select count(*) as ctr from users where username='foo' and password='\' or \'1\'=\'1' limit 1" phpsu is a phpschool

Nothing in the database and the password match. Just a simple steps to block a Web application in a big loophole. Here come the experience is and always should be the SQL query the user input to escape.

However, there are several security loopholes need to block. GET is a manipulation of variables.

GET prevent users manipulate variables

The previous one, preventing the abnormal user password to log in. If you're smart, you should learn of the ways to ensure that the SQL statement of all users to enter escaped.

However, users now have a secure login. Users have a valid password, does not mean that he will act in accordance with the rules - he has a lot of opportunities to cause harm. For example, the application may allow users to view special content. All links to template.php? Pid = 33 or template.php? Pid = 321 this position. In the URL as part of a question mark behind the query string. Because the query string directly on the URL, also known as GET query string.
www.phpsu.com


In PHP, if disabled register_globals, you can use $ _ GET [ 'pid'] visit to this string. In template.php page, and the implementation of the list may be similar to the August operation.

8 list. Example template.php

<?php
$pid = $_GET['pid'];
//we create an object of a fictional class Page
$obj = new Page;
$content = $obj->fetchPage($pid);
//and now we have a bunch of PHP that displays the page
?> do you kown phpsu.com?

What is wrong here? » First of all, here implicitly believed to come from the browser GET variable pid is safe. What happens is this » Most users not so smart, can not be constructed semantic attacks. However, if they have noticed that the browser's URL location domain pid = 33, could start trouble. If they enter another figure, there may be no problem, but if you type something else, such as SQL commands or enter the name of a file (such as / etc / passwd), or engage in other mischief, such as the importation of up to 3,000 characters Numerical, then what will happen? »

Under such circumstances, the basic rules to remember, do not trust user input. Application developers know template.php accept the personal identifier (PID) should be the number, so you can use the PHP is_numeric () function to ensure that the figures do not accept non-PID, as follows:

List 9. Use is_numeric () to limit the GET variable

<?php
$pid = $_GET['pid']; do you kown phpsu.com?
if (is_numeric($pid)){
    //we create an object of a fictional class Page
    $obj = new Page;
    $content = $obj->fetchPage($pid);
    //and now we have a bunch of PHP that displays the page
}else{
    //didn't pass the is_numeric() test, do something else!
}
?>

http://www.phpsu.com

This approach seems to be effective, but the following can easily enter through is_numeric () checks:

100 (effective)
100.1 (there should not be decimals)
+0123.45 E6 (scientific counting method - bad)
0xff33669f (hex - Danger, Danger!)

Well, there are safety awareness of the PHP developers how to do it » Years of experience shows that the best approach is to use regular expressions to ensure that the entire GET variables from the numbers, as follows:

List of 10. Restrict the use of the regular expression GET variable

<?php
$pid = $_GET['pid'];
if (strlen($pid)){
    if (!ereg("^[0-9]+$",$pid)){
        //do something appropriate, like maybe logging them out or sending them back to home page
    }
}else{
    //empty $pid, so send them back to the home page
}
//we create an object of a fictional class Page, which is now

phpsu.com is a free phpscool


//moderately protected from evil user input
$obj = new Page;
$content = $obj->fetchPage($pid);
//and now we have a bunch of PHP that displays the page
?>
phpsu.com

Need to do is use strlen () check whether the length of variable non-zero, if yes, on the use of an all-digital regular expressions are to ensure that data elements are effective. If PID contain letters, slashes, dots and hex or any similar content, then this routine catch it and pages from the user's activities in the shield. If behind-the-scenes look at the Page class, you'll see a sense of security of PHP developers have the user input $ pid had escaped, thereby protecting the fetchPage () method, as follows:

List 11. The fetchPage () method of escape

<?php
class Page{
    function fetchPage($pid){
        $sql = "select pid,title,desc,kw,content,status from page where pid='".mysql_real_escape_string($pid)."'";
    }
}
?>

phpsu提供的php教程

You might ask, "Since the figures have to ensure that PID is, then why should we conduct escaped» "because they do not know how many different in the context of the situation and will use fetchPage () method. Must call this method in all areas to protect, and the method of escape embodies the defense in depth the meaning.

If the user attempts to enter the very long value, such as up to 1,000 characters, trying to launch a buffer overflow attacks, then what will happen? » The next section more detailed discussion of this issue, but now you can add another check to ensure that the importation of the PID have the right length. Did you know that the database pid field the maximum length is five, so you can add the following inspection.

List of 12. Using regular expressions and to limit the length of inspection GET variable

<?php
$pid = $_GET['pid'];
if (strlen($pid)){
    if (!ereg("^[0-9]+$",$pid) && strlen($pid) > 5){ phpsu
        //do something appropriate, like maybe logging them out or sending them back to home page
    }
} else {
    //empty $pid, so send them back to the home page
}
    //we create an object of a fictional class Page, which is now
    //even more protected from evil user input
    $obj = new Page;
    $content = $obj->fetchPage($pid);
    //and now we have a bunch of PHP that displays the page
?> do you kown phpsu.com?

Now, no one can in the database application in 5000 into one of the figures - at least in relation to GET string of no such circumstances. Imagine the hackers trying to break through your application and was frustrated when Yaoyaqiechi look! But also because of the closure of the error report, the hackers more difficult to conduct reconnaissance.

Buffer overflow attacks

Buffer overflow attacks tried to make PHP applications (or, more precisely, in the bottom of the operating system or Apache) of memory allocation buffer overflow occurred. Remember, you may be using PHP such a high-level language to write Web applications, but in the end is to call C (in Apache circumstances). Like the majority of low-level language, C for memory allocation strict rules.

Buffer overflow attacks sent large amounts of data to the buffer zone, adjacent to the overflow of the data buffer memory, thereby undermining the buffer zone or a rewrite of logic. This can result in denial of service, the destruction of data on a remote server or execute malicious code.
welcome to phpsu.com


To prevent buffer overflow attacks is the only way to check the length of all user input. For example, if a form elements asked to enter your user name, then in this domain to add value to the maxlength 40 properties, and in the back-end use substr () to be checked. List of 13 forms and PHP code gives a brief example.

List of 13. Check the length of user input

<?php
if ($_POST['submit'] == "go"){
    $name = substr($_POST['name'],0,40);
}
?>
<form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post">
<p><label for="name">Name</label>
<input type="text" name="name" id="name" size="20" maxlength="40"/></p>
<p><input type="submit" name="submit" value="go"/></p>
</form> phpsu提供的php教程

Why not only provide maxlength attributes, and in the back-end to substr () check » Because the defense in depth is always good. Browser to prevent users enter or MySQL PHP can not safely handle the long string (imagine someone trying to enter up to 1,000 characters of the name), while the back-end PHP inspection will ensure that no one remotely or manipulation in a browser form Data.

As you can see, this approach with the one used in the strlen () check the length of GET pid similar variables. In this example, the length of more than five ignored the importation of any value, but it's easy to value truncated to the appropriate length, as follows:

List of 14. Enter the GET variable to change the length of

<?php
$pid = $_GET['pid'];
if (strlen($pid)){
    if (!ereg("^[0-9]+$",$pid)){
        //if non numeric $pid, send them back to home page
    }
}else{ http://www.phpsu.com
    //empty $pid, so send them back to the home page
}
    //we have a numeric pid, but it may be too long, so let's check
    if (strlen($pid)>5){
        $pid = substr($pid,0,5);
    }
    //we create an object of a fictional class Page, which is now
    //even more protected from evil user input
    $obj = new Page;
    $content = $obj->fetchPage($pid);
    //and now we have a bunch of PHP that displays the page
?> phpsu提供的php教程

Note that a buffer overflow attacks are not confined to a long string of numbers or letters string. Might also see a long string of hexadecimal (often looks like \ xA3 or \ xFF). Remember that any buffer overflow attacks are inundated specific purpose of the buffer zone, and malicious code or put under the command of a buffer zone, thus undermining the implementation of data or malicious code. Hexadecimal buffer overflow to deal with the simplest way is not allowed to enter more than a specific length.

If you deal with is in the database to allow the importation of a longer entry form text area, then the client can not easily limit the length of data. PHP after landing in the data, you can use regular expressions to remove any hex as the string.

List of 15. Hexadecimal string to prevent

<?php
if ($_POST['submit'] == "go"){
    $name = substr($_POST['name'],0,40);
    //clean out any potential hexadecimal characters

welcome to phpsu.com


    $name = cleanHex($name);
    //continue processing....
}
function cleanHex($input){
    $clean = preg_replace("![\][xX]([A-Fa-f0-9]{1,3})!", "",$input);
    return $clean;
}
?>
<form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post">
<p><label for="name">Name</label>
<input type="text" name="name" id="name" size="20" maxlength="40"/></p>
<p><input type="submit" name="submit" value="go"/></p>
</form> phpsu提供的php教程

You may find this series of the operation a bit too strict. After all, the hexadecimal string a legitimate purpose, such as foreign language characters in the output. How to deploy hexadecimal regex from your own decision. A better strategy is that only in a row contained too many hexadecimal string, or when the string of characters over a specific number (for example, 128 or 255), only to delete HEX string.

Cross-site scripting attacks

In cross-site scripting (XSS) attacks, often in the form of a malicious user (or user input through other means) to enter information, which will enter a malicious client tag insertion process or in the database. For example, if site visitors have a simple register of procedures, so that visitors can leave their names, e-mail address and a brief message. Malicious users can use this opportunity to insert a brief news outside of things, such as inappropriate for other users of the image or to redirect your users to another site Javascrīpt, or theft of cookie information.

phpsu is a phpschool



We are fortunate that, PHP has provided strip_tags () function, this function can remove any HTML tags in the siege of the contents. strip_tags () function also allows tags to provide a list of permitted, such as <b> or <i>.

Browser data manipulation

There is a category of browser plug-in allows users to tamper with his head on the page elements and form elements. The use of Tamper Data (a Mozilla plug-in), can be easily manipulated contains many hidden text field a simple form, sent to the PHP and MySQL command.

Users to click on the Submit form before he can start Tamper Data. In the form, he will see a list of form data field. Tamper Data allows users to tamper with these data, and then complete the form to the browser.

Let us return to the front of the establishment of the sample. I have already checked the length of the string to remove the HTML tags and delete the hexadecimal characters. However, to add some hidden text field, as follows: phpsu

List of 17. Hidden variables

<?php
if ($_POST['submit'] == "go"){
    //strip_tags
    $name = strip_tags($_POST['name']);
    $name = substr($name,0,40);
    //clean out any potential hexadecimal characters
    $name = cleanHex($name);
    //continue processing....
}
function cleanHex($input){
    $clean = preg_replace("![\][xX]([A-Fa-f0-9]{1,3})!", "",$input);
    return $clean;
}
?>
<form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post">
<p><label for="name">Name</label>
<input type="text" name="name" id="name" size="20" maxlength="40"/></p>
<input type="hidden" name="table" value="users"/>

phpsu is a phpschool

<input type="hidden" name="action" value="create"/>
<input type="hidden" name="status" value="live\"/>
<p><input type="submit" name="submit" value="go"/></p>
</form>
phpsu

Note that exposed the hidden variables of the table: users. Also see a value to create the action field. As long as a basic SQL experience, we can see that these orders may be in control of middleware in a SQL engine. Xianggao the destruction of the people simply change the form or provide another option, such as delete.

Now what is left » Remote form submission.

Remote form submission

Web can share the benefits of information and services. Disadvantages also can share information and services, because some people do things impunity.

To form as an example. No one can visit a Web site, and use the browser on the File> Save As the establishment of the local copy of the form. Then, he can modify parameters of action to point to a fully qualified URL (do not point to formHandler.php, but at the http://www.yoursite.com/formHandler.php, because in this form on the site), so he hoped that the Any changes, click Submit, the server will form data communications flow as a legitimate receiver.

phpsu is a phpschool



First check may consider $ _ SERVER [ 'HTTP_REFERER'], to determine whether the request from its own servers, this method can block the majority of malicious users, but unstoppable maximum prescribed hackers. These were smart enough to tamper with the head of the referrer information, a copy of the form of long-range look like from your server submitted.

To deal with long-range form a better way, based on a string or time-stamp the only generate a token and this token on the session variables and form. After submit the form to check whether the two token match. If we do not match, we knew it was trying to send a copy of the form of remote data.

To create a random token, you can use the built-in PHP md5 (), uniqid () and the rand () function, as follows:

List of 18. To form long-range defense

<?php
session_start();
if ($_POST['submit'] == "go"){
    //check token
    if ($_POST['token'] == $_SESSION['token']){ phpsu is a phpschool
        //strip_tags
        $name = strip_tags($_POST['name']);
        $name = substr($name,0,40);
        //clean out any potential hexadecimal characters
        $name = cleanHex($name);
        //continue processing....
    }else{
        //stop all processing! remote form posting attempt!
    }
}
$token = md5(uniqid(rand(), true));
$_SESSION['token']= $token;
function cleanHex($input){
    $clean = preg_replace("![\][xX]([A-Fa-f0-9]{1,3})!", "",$input);
    return $clean;
}
?>
<form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post">
<p><label for="name">Name</label> phpsu.com is a free phpscool
<input type="text" name="name" id="name" size="20" maxlength="40"/></p>
<input type="hidden" name="token" value="<?php echo $token;?>"/>
<p><input type="submit" name="submit" value="go"/></p>
</form>

www.phpsu.com

This technology is effective, it is because in PHP session data between the server could not move. Even if some people get your PHP source code, it will be transferred to their own servers, and your server to the information, your server to receive the only empty or deformity of the conversation token and the original form of tokens . They do not match, remote on the failure to submit the form.

phpsu.com is a free phpscool


TITLE:PHP security rules
Copyright 2008 The PHPsu All rights reserved. This mirror generously provided by: .Hp Inc.
Last updated: Fri Jun 6 22:59:05 GMT-8 2008