In-depth analysis of seven habits of writing secure PHP applications

Source: Internet
Author: User
Tags form post sql injection example
This article gives a detailed analysis of the seven habits of writing a security-PHP application. if you need a friend, pay attention to the security issues, in addition to the actual platform and operating system security issues, you also need to ensure that you write secure applications. When writing a PHP application, apply the following seven habits to ensure the best security of the application:
• Verification input
• Protect file systems
• Protect databases
• Protect session data
• Cross-site scripting (XSS) vulnerability protection
• Validation form post
• Cross-Site Request Forgeries (CSRF) protection

Verification input
When talking about security issues, verifying data is the most important habit you may use. When it comes to input, it is very simple: do not trust users. Your users may be excellent, and most users may use the application as expected. However, as long as the input opportunity is provided, there may be very bad input. As an application developer, you must prevent the application from receiving incorrect input. Careful consideration of the locations and correct values entered by the user will allow you to build a robust and secure application.
This article introduces the interaction between the file system and the database, General verification tips for various verifications are listed below:
• Use values in the whitelist
• Always reverify limited options
• Use built-in escape functions
• Verify the correct data type (such as numbers)
The value (White-listed value) in the whitelist is the correct value, which is opposite to the invalid Black-listed value. The difference between the two is that during verification, the list or range of possible values is smaller than the list or range of invalid values, many of which may be unknown values or unexpected values.
When performing verification, remember that it is generally easier to design and verify the value that the application allows to use than to prevent all unknown values. For example, to limit the field value to all numbers, you need to write a routine to ensure that all input values are numbers. Do not compile a routine that is used to search for non-numeric values and is marked as invalid when a non-numeric value is found.

Protect file systems
In July 2000, a Web site leaked customer data stored in Web server files. A visitor of the Web site uses a URL to view files containing data. Although the file is misplaced, this example highlights the importance of protecting the file system for attackers.
If the PHP application processes the file at will and contains variable data that can be entered by the user, check the user input carefully to ensure that the user cannot perform any inappropriate operations on the file system. Listing 1 shows a sample PHP Site for downloading images with a specified name.
Listing 1. download an object

The 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 dangerous scripts in listing 1 process all the files that the Web server has read permission to, including the files in the session directory (see "protect session data "), it even includes some system files (such as/etc/passwd ). For demonstration, this example uses a text box that allows you to type a file name, but you can easily provide a file name in the query string.
Configuring user input and file system access permissions at the same time is very dangerous, so it is best to design the application to use the database and hide the generated file name to avoid simultaneous configuration. However, this is not always effective. Listing 2 provides sample routines for verifying file names. It uses regular expressions to ensure that only valid characters are used in the file name, and the dot character:... is checked in particular :...
Listing 2. check valid file name characters

The code is as follows:


Function isValidFileName ($ file ){
/* Don't allow .. and allow any "word" character \/*/
Return preg_match ('/^ (((? :\.)(?! \.) | \ W) + $/', $ file );
}


Protect databases
In April 2008, the prison administration of a certain U.S. state used the SQL column name in the query string, which leaked confidential data. This leak allows malicious users to select columns to be displayed, submit pages, and obtain data. This leak shows how users can execute input in unpredictable ways, and shows the necessity to defend against SQL injection attacks.
Listing 3 shows the sample script for running SQL statements. In this example, SQL statements are dynamic statements that allow the same attacks. The owner of this form may think that the form is safe because they have defined the column name as a selection list. However, the code ignores the last habit of form spoofing-limiting the option to a drop-down box does not mean that others cannot publish a form containing the required content (including the asterisk [*]).
Listing 3. execute SQL statements

The code is as follows:




SQL Injection Example



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 protect the database, try to avoid using dynamic SQL code. If dynamic SQL code cannot be avoided, do not directly use the input for the column. Listing 4 shows that in addition to using static columns, you can also add a simple verification routine to the account number field to ensure that the input value is not a non-numeric value.
Listing 4. protection through verification and mysql_real_escape_string ()

The code is as follows:




SQL Injection Example



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 "".
"Please supply a valid account number! ";
}
}
?>



This example also shows the usage of the mysql_real_escape_string () function. This function filters your input correctly, so it does not include invalid characters. If you have been dependent on magic_quotes_gpc, you must note that it has been discarded and will be deleted in PHP V6. Avoid using it from now on and write secure PHP applications in this case. In addition, if ISP is used, it is possible that magic_quotes_gpc is not enabled for your ISP.
Finally, in the improved example, you can see that the SQL statement and output do not include the dynamic column option. If you add columns to a table that later contains different information, you can output these columns. If you want to use the framework in combination with the database, your framework may have performed SQL verification for you. Ensure that documents are reviewed to ensure the security of the framework. if you are still unsure, verify the documents to ensure security. Other verification is required even if the framework is used for database interaction.

Protect sessions
By default, session information in PHP is written to the temporary directory. Consider the form in listing 5, which shows how to store the user ID and account number in the session.
Listing 5. storing data in a session

The code is as follows:


Session_start ();
?>


Storing session information


If ($ _ POST ['submit '] = 'save '){
$ _ SESSION ['username'] =_ _ POST ['username'];
$ _ SESSION ['accountnumber'] = $ _ POST ['accountnumber'];
}
?>




Listing 6 shows the content of the/tmp directory.
Listing 6. session files in the/tmp Directory

The code is as follows:


-Rw ------- 1 _ www wheel 97 Aug 18 20:00 sess_9e4233f2cd7cae35866cd8b61d9fa42b


As you can see, during output (see listing 7), session files contain information in a very readable format. Since the file must be read and written by Web server users, session files may cause serious problems for all users on the shared server. Someone except you can write scripts to read these files, so you can try to retrieve the value from the session.
Listing 7. session file content

The code is as follows:


UserName | s: 5: "ngood"; accountNumber | s: 9: "123456789 ";


Storage password
No matter in the database, session, file system, or any other form, passwords cannot be stored as plain text. The best way to process passwords is to encrypt and store passwords that are encrypted. In practice, passwords are still stored in plain text. If you use a Web site that can send a password instead of reset a password, it means that the password is stored in plain text or the code for decryption can be obtained (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 you put into the session. However, encrypted data does not mean absolute security. Therefore, use this method as the only way to protect sessions. The alternative is to store session data in other locations, such as databases. You still have to ensure that the database is locked, but this solution solves two problems: first, it puts data in a safer location than the shared file system; second, it makes it easier for your applications to span multiple Web servers and share sessions across multiple hosts.

To implement session persistence, see the session_set_save_handler () function in PHP. You can store session information in a database or implement a processing program used to encrypt and decrypt all data. Listing 8 provides implementation function usage and function skeleton examples. You can also view how to use the database in the reference section.
Listing 8. Sample session_set_save_handler () function

The 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 ");


Protects against XSS vulnerabilities
XSS vulnerabilities represent most of the vulnerabilities on all archived Web sites in 2007 (see references ). When a user can inject HTML code into your Web page, an XSS vulnerability occurs. HTML code can carry JavaScript code in the script tag, so JavaScript can be run as long as the page is extracted. The form in listing 9 can represent a forum, wiki, social network, or any other site that can input text.
Listing 9. input text form

The code is as follows:




Your chance to input XSS






Listing 10 demonstrates how to output results from forms that allow XSS attacks.
Listing 10. showResults. php

The code is as follows:




Results demonstrating XSS


Echo ("

You typed this:

");
Echo ("

");
Echo ($ _ POST ['mytext']);
Echo ("

");
?>



Listing 11 provides a basic example in which a new window is displayed and the Google homepage is opened. If your Web application is not protected against XSS attacks, it will cause serious damage. For example, a person can add links that mimic the site style to achieve the goal of spoofing (see references ).
Listing 11. malicious text input example

The code is as follows:


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.