Seven habits in-depth analysis of writing secure PHP applications _php tutorial

Source: Internet
Author: User
Tags form post sql injection example csrf attack
When it comes to security issues, be aware that you need to ensure that you write secure applications in addition to the actual platform and operating system security issues. When writing a PHP application, apply the following seven habits to ensure the best security for your application:
• Validate input
• File System Protection
• Protect the database
• Protect session data
• Protect cross-site scripting (Cross-site SCRIPTING,XSS) vulnerabilities
• Test Form Post
• Protection against cross-site request forgery (Cross-site requests FORGERIES,CSRF)

Validate input
Validating data is the most important habit you may adopt when referring to security issues. And when it comes to input, it's very simple: don't trust the user. Your users may be excellent, and most users may use the application exactly as expected. However, as long as the opportunity to enter is provided, there is a high likelihood of very bad input. As an application developer, you must prevent the application from accepting the wrong input. Careful consideration of the user input location and the correct value will allow you to build a robust and secure application.
Although the following article describes the file system interaction with the database, The following is a list of general validation tips for various validations
• Use values from the whitelist
• Always re-verify limited options
• Use the built-in escape function
• Verify the correct data type (such as number)
The value in the whitelist (white-listed value) is the correct value, as opposed to the invalid blacklist value (black-listed value). The difference between the two is that when validating, the list or range of possible values is less than the list or range of invalid values, many of which may be unknown values or unexpected values.
When validating, it is often easier to design and validate the values that your application allows to use than to prevent all unknowns. For example, to limit field values to all numbers, you need to write a routine that ensures that the inputs are all numbers. Do not write routines that are used to search for non-numeric values and are marked as invalid when a non-numeric value is found.

Protect File Systems
In July 2000, a Web site disclosed customer data that was stored in a file in the Web server. A visitor to the Web site uses the URL to view the files that contain the data. Although the file was misplaced, this example highlights the importance of protecting the file system against attackers.
If the PHP application handles the file arbitrarily and contains variable data that the user can enter, double-check the user input to ensure that the user cannot perform any inappropriate actions on the file system. Listing 1 shows an example of a PHP site that downloads an image with the specified name.
Listing 1. Download the file
Copy CodeThe code is as follows:
if ($_post[' submit '] = = ' Download ') {
$file = $_post[' fileName '];
Header ("Content-type:application/x-octet-stream");
Header ("Content-transfer-encoding:binary");
Header ("content-disposition:attachment; Filename=\ "". $file. "\";" );
$fh = fopen ($file, ' R ');
while (! feof ($FH))
{
Echo (Fread ($FH, 1024));
}
Fclose ($FH);
} else {
Echo ("< ");
Echo ("Title>guard your filesystem");
Echo ("");
}

As you can see, the more dangerous script in Listing 1 will handle all the files that the WEB server has read access to, including the files in the Session directory (see "Securing Session Data"), and even some system files (such as/etc/passwd). For demonstration purposes, this example uses a text box that allows the user to type a file name, but can easily provide a file name in the query string.
While configuring user input and file system access is risky, it is a good idea to design your application to use the database and hide the generated file names to avoid simultaneous configuration. However, this does not always work. Listing 2 provides a sample routine to verify the file name. It will use regular expressions to ensure that only valid characters are used in the file name, and specifically check for dot characters: ...
Listing 2. Check for valid file name characters
Copy CodeThe code is as follows:
function Isvalidfilename ($file) {
/* don ' t allow. and allow any "word" character \/* *
Return Preg_match ('/^ (?: \.) (?! \.))| \w) +$/', $file);
}

Protecting databases
In April 2008, the Prison Bureau of a certain state of the United States used SQL column names in the query string, thus disclosing confidential data. This disclosure allows a malicious user to select columns to display, submit pages, and obtain data. The leak shows how users can execute input in a way that the application developer cannot anticipate, and shows the need to defend against SQL injection attacks.
Listing 3 shows a sample script that runs the SQL statement. In this case, the SQL statement is a dynamic statement that allows the same attack. The owner of this form may consider the form to be safe because they have qualified the column name as the selection list. However, the code neglects the last habit of form spoofing-the code restricting the option to a drop-down box does not mean that others will not be able to publish a form that contains the required content (including asterisks [*]).
Listing 3. Executing SQL statements
Copy CodeThe code is as follows:


<title>SQL Injection Example</title>



if ($_post[' submit '] = = ' Save ') {
/* Do the form processing */
$link = mysql_connect (' hostname ', ' user ', ' password ') or
Die (' Could not Connect '. Mysql_error ());
mysql_select_db (' Test ', $link);

$col = $_post[' col '];
$select = "Select". $col. "From account_data WHERE account_number ="
. $_post[' Account_number '. ";" ;
Echo '

' . $select. '

';
$result = mysql_query ($select) or Die ('

' . Mysql_error (). '

');
Echo '





'; while ($row = Mysql_fetch_assoc ($result)) {echo ' '; Echo ' '; Echo ' '; } Echo '
' . $row [$col]. '
';
Mysql_close ($link);
}
?>



Therefore, to form the habit of protecting your database, avoid using dynamic SQL code whenever possible. If you cannot avoid dynamic SQL code, do not use input directly on the column. Listing 4 shows that in addition to using static columns, you can also add a simple validation routine to the account number field to ensure that the input value is not a non-numeric value.
Listing 4: Providing protection through validation and mysql_real_escape_string ()
Copy CodeThe code is as follows:


<title>SQL Injection Example</title>



function Isvalidaccountnumber ($number)
{
Return Is_numeric ($number);
}
if ($_post[' submit '] = = ' Save ') {
/* Remember habit #1--validate your data! */
if (Isset ($_post[' Account_number ')) &&
Isvalidaccountnumber ($_post[' Account_number ')) {
/* Do the form processing */
$link = mysql_connect (' hostname ', ' user ', ' password ') or
Die (' Could not Connect '. Mysql_error ());
mysql_select_db (' Test ', $link);
$select = sprintf ("Select Account_number, Name, address".
"From Account_data WHERE account_number =%s;",
Mysql_real_escape_string ($_post[' account_number '));
Echo '

' . $select. '

';
$result = mysql_query ($select) or Die ('

' . Mysql_error (). '

');
Echo '







'; while ($row = Mysql_fetch_assoc ($result)) {echo ' '; Echo ' '; Echo ' '; Echo ' '; Echo ' '; } Echo '
' . $row [' Account_number ']. '' . $row [' name ']. '' . $row [' Address ']. '
';
Mysql_close ($link);
} else {
echo " " .
"Supply a valid account number!";
}
}
?>



This example also shows the use of the mysql_real_escape_string () function. This function will correctly filter your input, so it does not include invalid characters. If you have been relying on MAGIC_QUOTES_GPC, be aware that it has been deprecated and will be removed in PHP V6. You should avoid using it from now on and write a secure PHP application in this case. In addition, if you are using an ISP, it is possible that your ISP does not have MAGIC_QUOTES_GPC enabled.
Finally, in the improved example, you can see that the SQL statement and the output do not include the dynamic column option. Using this method, you can output columns if you add them to a table that later contains different information. If you want to use a framework to work with a database, your framework might have performed SQL validation for you. Ensure that the document is consulted to ensure the security of the framework, and if you are still unsure, verify to ensure that it is secure. Even if you use the framework for database interaction, you still need to perform additional validation.

Protect Sessions
By default, session information in PHP is written to the temp directory. Consider the form in Listing 5, which will show how to store the user ID and account number in the session.
Listing 5. Storing data in a session
Copy CodeThe code is as follows:
Session_Start ();
?>


<title>Storing session information</title>


if ($_post[' submit '] = = ' Save ') {
$_session[' userName '] = $_post[' userName '];
$_session[' accountnumber '] = $_post[' AccountNumber '];
}
?>




Listing 6 shows the contents of the/tmp directory.
Listing 6. Session files in the/tmp directory
Copy CodeThe code is as follows:
-RW-------1 _www wheel 20:00 sess_9e4233f2cd7cae35866cd8b61d9fa42b

As you can see, in the output (see listing 7), the session file contains information in a very readable format. Because the file must be read and written by the WEB server user, the session file can cause serious problems for all users on the shared server. Someone other than you can write a script to read the files, so you can try to fetch the values from the session.
Listing 7: Contents of the session file
Copy CodeThe code is as follows:
Username|s:5: "Ngood"; Accountnumber|s:9: "123456789";

Store Password
Regardless of whether it is in a database, session, file system, or any other form, the password must never be stored as plain text. The best way to process a password is to encrypt it and compare the encrypted password to each other. Nonetheless, in practice people still store passwords in plain text. Whenever you use a Web site that can send a password instead of resetting it, it means that the password is stored in plain text or you can get the code to decrypt (if encrypted). Even the latter, you can find and use the decryption code.
You can take two actions to protect session data. The first is to encrypt all the content that you put into the session. However, because encrypting data does not imply absolute security, it is prudent to use this approach as the only way to protect your session. The alternative is to store session data in a different location, such as a database. You must still ensure that the database is locked, but this approach will solve two problems: first, it will put the data in a more secure location than the shared file system, and second, it will make it easier for your application to span multiple Web servers while sharing sessions can span multiple hosts.

To implement your own session persistence, see the Session_set_save_handler () function in PHP. With it, you can store session information in a database, or you can implement a handler for encrypting and decrypting all data. Listing 8 provides an example of the implemented function usage and function skeleton. You can also see how to use the database in the Resources section.
Listing 8. Session_set_save_handler () Function Example
Copy CodeThe code is as follows:
function open ($save _path, $session _name)
{
/* Custom code */
return (true);
}
function Close ()
{
/* Custom code */
return (true);
}
function Read ($id)
{
/* Custom code */
return (true);
}
function Write ($id, $sess _data)
{
/* Custom code */
return (true);
}
function Destroy ($ID)
{
/* Custom code */
return (true);
}
Function GC ($MAXLIFETIME)
{
/* Custom code */
return (true);
}
Session_set_save_handler ("Open", "close", "read", "write", "Destroy", "GC");

Protection against XSS vulnerabilities
XSS vulnerabilities represent most of the vulnerabilities of all archived Web sites in 2007 (see Resources). An XSS vulnerability occurs when a user is able to inject HTML code into your Web page. HTML code can carry JavaScript code in script markup, so that JavaScript is allowed to run as long as the page is extracted. The form in Listing 9 can represent a forum, wiki, social network, or any other site where text can be entered.
Listing 9: Entering text form
Copy CodeThe code is as follows:


<title>Your chance to input XSS</title>






Listing 10 shows how a form that allows XSS attacks can output results.
Listing 10. showresults.php
Copy CodeThe code is as follows:


<title>Results demonstrating XSS</title>


Echo ("

You typed this:

");
Echo ("

");
Echo ($_post[' myText ');
Echo ("

");
?>



Listing 11 provides a basic example in which a new window pops up and opens the Google home page. If your WEB application does not protect against XSS attacks, it can cause serious damage. For example, someone can add a link that mimics the site style for spoofing (phishing) purposes (see Resources).
Listing 11: Sample Malicious input text
Copy CodeThe code is as follows:


To prevent XSS attacks, as long as the value of the variable is printed to the output, the input needs to be filtered through the htmlentities () function. Remember to follow the first habit of validating the input data with the values in the whitelist in the name of the Web application, the e-mail address, the phone number, and the input to the billing information.
The following shows a more secure page for displaying text input.
listing 12. More Secure Forms
Copy CodeThe code is as follows:


<title>Results demonstrating XSS</title>


Echo ("

You typed this:

");
Echo ("

");
Echo (Htmlentities ($_post[' myText '));
Echo ("

");
?>



Protection against invalid post
Form spoofing refers to someone sending a post from an inappropriate location to your form. The simplest way to cheat a form is to create a Web page that delivers all the values by submitting to the form. Because the WEB application is stateless, there is no absolutely feasible way to ensure that the published data comes from the specified location. Everything can be spoofed from an IP address to a host name. Listing 13 shows a typical form that allows you to enter information.
listing 13. Forms for working with text
Copy CodeThe code is as follows:


<title>Form Spoofing Example</title>


if ($_post[' submit '] = = ' Save ') {
Echo ("

I am Processing your text: ");
Echo ($_post[' myText ');
Echo ("

");
}
?>



Listing 14 shows the form that will be published in the form shown in Listing 13. To try this, you can put the form on your Web site and save the code in Listing 14 as an HTML document on your desktop. After you save the form, open the form in the browser. You can then fill in the data and submit the form to see how the data is processed.
listing 14. Forms for collecting data
Copy CodeThe code is as follows:


<title>Collecting Your data</title>






The potential impact of form spoofing is that if you have a form with a drop-down box, radio button, check box, or other restricted input, the restrictions do not make any sense when the form is spoofed. Consider the code in Listing 15, which contains a form with invalid data.
listing 15. Forms with Invalid data
Copy CodeThe code is as follows:


<title>Collecting Your data</title>






think about it for a moment:If you have a drop-down box or radio button that restricts user input, you might think you don't have to worry about validating the input. After all, the input form will ensure that the user can only enter some data, right? To restrict forms spoofing, validation is required to ensure that the identity of the publisher is true. You can use a one-time use tag, although this technique still does not ensure that the form is absolutely secure, but it makes form spoofing more difficult. Because the tag is changed every time the form is called, it is necessary to get an instance of the sending form, remove the tag, and put it on a fake form if you want to be an attacker. Using this technique prevents malicious users from building persistent Web tables forms to publish inappropriate requests to the application. Listing 16 provides an example of a form tag.
Listing 16. Use a one-time form marker
Copy CodeThe code is as follows:
Session_Start ();
?>


<title>SQL Injection Test</title>


Echo ' Session token= '. $_session[' token '];
Echo '
';
Echo ' Token from form= '. $_post[' token '];
Echo '
';
if ($_session[' token '] = = $_post[' token ')} {
/* Cool, it's all good ... create another one */
} else {
Echo '

Go away!

';
}
$token = MD5 (Uniqid (rand (), true));
$_session[' token '] = $token;
?>




Protection against CSRF
Cross-site request forgery (CSRF attack) is the result of executing an attack with user rights. In a CSRF attack, your users can easily become unexpected accomplices. Listing 17 provides an example of a page that performs a specific action. This page will look for user login information from the cookie. As long as the cookie is valid, the Web page processes the request.
listing 17. CSRF Example
Copy CodeThe code is as follows:


CSRF attacks are usually made in the form of tokens, because the browser will not knowingly invoke the URL to obtain an image. However, the image source can be a page URL in the same site that is processed according to the incoming parameters. When this tag is combined with an XSS attack-the most common in an archived attack-the user can easily take some action on their credentials without knowing it-and therefore forged.
To protect you from CSRF attacks, you need to use the one-time tagging method used when verifying a form post. Also, use an explicit $_post variable instead of $_request. Listing 18 shows a bad example of working with the same Web page-whether the page is called through a GET request or by publishing the form to a page.
listing 18. Getting Data from $_request
Copy CodeThe code is as follows:


<title>Processes both posts and gets</title>


if ($_request[' submit '] = = ' Save ') {
Echo ("

I am Processing your text: ");
Echo (htmlentities ($_request[' text "));
Echo ("

");
}
?>



Listing 19 shows a clean page that uses only form POST.
Listing 19: Getting Data from $_post only
Copy CodeThe code is as follows:


<title>Processes both posts and gets</title>


if ($_post[' submit '] = = ' Save ') {
Echo ("

I am Processing your text: ");
Echo (htmlentities ($_post[' text "));
Echo ("

");
}
?>



concluding remarks
Starting with these seven habits and trying to write a more secure PHP WEB application can help you avoid being a victim of malicious attacks. Like many other habits, these habits may be difficult to adapt to at first, but it will become more and more natural to follow these habits over time.
Remember that the first habit is the key: Validate input. After you ensure that the input does not include an invalid value, you can continue to protect the file system, database, and session. Finally, make sure that your PHP code is resistant to XSS attacks, form spoofing, and CSRF attacks. Forming these habits can help you resist some simple attacks.

http://www.bkjia.com/PHPjc/327487.html www.bkjia.com true http://www.bkjia.com/PHPjc/327487.html techarticle when it comes to security issues, be aware that you need to ensure that you write secure applications in addition to the actual platform and operating system security issues. When writing a PHP application, ...

  • Related Article

    Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.