Analysis of the causes of PHP program vulnerabilities and the methods to prevent them _php skills

Source: Internet
Author: User
Tags error handling php script sql injection first row time interval

Misuse of include

1. The reason of the loophole:

Include is the most commonly used function in writing PHP Web sites, and supports relative paths. There are many PHP scripts that directly take an input variable as an include parameter, resulting in arbitrary reference scripts, absolute path leaks and other vulnerabilities. Look at the following code:

...
$includepage =$_get["Includepage"];
Include ($includepage);
...

Obviously, we just need to submit a different includepage variable to get the desired page. If you submit a nonexistent page, you can make the PHP script error and reveal the actual absolute path (the solution to this problem is described in the following article).

2. Vulnerability Resolution:

The solution to this vulnerability is simple, that is, to determine whether the page exists before the include. Or, more strictly, use arrays to make provisions for files that can be include. Look at the following code:

Copy Code code as follows:

$pagelist =array ("test1.php", "test2.php", "test3.php"); This provides the documentation that can be used to include
if (Isset ($_get["Includepage"))//Judge if there is $includepage
{
$includepage =$_get["Includepage"];
foreach ($pagelist as $prepage)
{
if ($includepage = = $prepage)//Check whether the file is in the Allow list
{
Include ($prepage);
$checkfind =true;
Break
}
}
if ($checkfind ==true) {unset ($checkfind);}
Else{die ("Invalid reference page!") "); }
}

This will be a good solution to the problem.

Tip: The function that has this problem also has: require (), require_once (), include_once (), ReadFile (), and so on, when writing also should notice.

The input variable is not filtered

1. The reason of the loophole:

This vulnerability was early in the ASP, and there were countless injection holes. But since PHP was less influential at the time, not too many people were able to pay attention. For PHP, this vulnerability has a greater impact than the ASP, because there are more PHP scripts used in the text database. Of course, there is an injection problem with SQL statements. For a more classic example, the first is the database:

Copy Code code as follows:

$id =$_get["id"];

$query = "SELECT * from my_table where id= '". $id. "'"; A classic SQL injection vulnerability
$result =mysql_query ($query);


It is clear that we can use injection to get the rest of the database. Here is no longer detailed description, and ASP injection, we can look at the previous black defense. And then we look at the problem with the text database:
Copy Code code as follows:

$text 1=$_post["Text1"];
$text 2=$_post["Text2"];
$text 3=$_post["Text3"];

$FD =fopen ("test.php", "a");
Fwrite ($FD, "\r\n$text1&line; $text 2&line; $text 3");
Fclose ($FD);


The loopholes in the text can be said to be more serious. If we commit a variable to insert a small PHP code, we can another text database test.php into a PHP back door. Even insert the upload code so that we can upload a perfect php back door. Then elevate the permissions, and the server is yours.

2. Vulnerability Resolution:

The solution to this vulnerability is simply to filter all the submitted variables in a strict manner. Replace some of the sensitive characters. We can use the Htmlspecialchars () function provided by PHP to replace the content of HTML. Here is an example:

Copy Code code as follows:

Constructing filter functions
function Flt_tags ($text)
{
$badwords =array ("Cao", "fuck"); Glossary filter List
$text =rtrim ($text);
foreach ($badwords as $badword)//The filtering of words here
{
if (Stristr ($text, $badword) ==true) {die (Error: The content you submitted contains sensitive words, please do not submit sensitive content.) "); }
}
$text =htmlspecialchars ($text); HTML replacement
These two lines replace the carriage return with the

$text =str_replace ("R", "", $text);
$text =str_replace ("\ n", "", $text);
$text =str_replace ("&line;", "│", $text); Text Database Separator "&line;" Replace with full corner "│"
$text =preg_replace ("/\s{2}/", "", $text); Space Replacement China Network Management Alliance
$text =preg_replace ("/\t/", "", $text); or a space replacement
if (GET_MAGIC_QUOTES_GPC ()) {$text =stripslashes ($text);///If Magic_quotes is turned on, replace with \
return $text;
}

$text 1=$_post["Text1"];
$text 2=$_post["Text2"];
$text 3=$_post["Text3"];

Filter All input
$text 1=flt_tags ($text 1);
$text 2=flt_tags ($text 2);
$text 3=flt_tags ($text 3);

$FD =fopen ("test.php", "a");
Fwrite ($FD, "\r\n$text1&line; $text 2&line; $text 3");
Fclose ($FD);


After a few substitutions and filtering, you can safely write data to a text or database.

Administrators are not completely judged

1. The reason of the loophole:

We use PHP to write scripts, which usually involve administrator permissions issues. Some scripts only make "yes" judgments on administrator rights, but often ignore "no" judgments. In the case of register_globals open in the PHP configuration file (4.2.0 after the version is closed by default, but many people open it for convenience, which is extremely dangerous behavior), there will be a submission variable posing as an administrator. Let's take a look at the example code:

Copy Code code as follows:

$cookiesign = "Admincookiesign"; To determine whether the admin cookie variable
$adminsign =$_cookie["sign"]; Get the user's cookie variable

if ($adminsign = = $cookiesign)
{
$admin =true;
}

if ($admin) {echo is now an admin state. "; }


Looks like a safe look, hehe. Now let's assume that the PHP configuration file is register_globals open. We submit such an address "test.php?" Admin=true ", the result see? We do not have the correct cookie, but because Register_globals is turned on, the admin variable we submitted is automatically registered as true. And the script lacks "no" judgment, which makes us successfully get the administrator's permission through Admin=true. This problem exists in most websites and forums.

2. Vulnerability Resolution:

To solve this problem, we just need to add a "no" to the admin in the script. We still assume that Register_globals is open in the PHP configuration file. Look at the code:

Copy Code code as follows:

$cookiesign = "Admincookiesign"; To determine whether the admin cookie variable
$adminsign =$_cookie["sign"]; Get the user's cookie variable

if ($adminsign = = $cookiesign)
{
$admin =true;
}
Else
{
$admin =false;
}
if ($admin) {echo is now an admin state. "; }


In this way, even if an attacker submits a admin=true variable without the correct cookie, the script will set the $admin to false in future judgments. This solves some of the problems. However, since $admin is a variable, a vulnerability in subsequent script references may cause a new crisis if the $admin is assigned a value. Therefore, we should use constants to hold the decision of administrator permissions. Use the Define () statement to define an admin constant to record administrator permissions, which can be followed by an error if the assignment is assigned again, for protection purposes. Look at the following code:
Copy Code code as follows:

$cookiesign = "Admincookiesign"; To determine whether the admin cookie variable
$adminsign =$_cookie["sign"]; Get the user's cookie variable

if ($adminsign = = $cookiesign)
{
Define (admin,true);
}
Else
{
Define (ADMIN,FALSE);
}
if (Admin) {Echo is now an admin state. "; }


It is worth noting that we used the Define statement, so before calling the admin constant, we should not use the variable symbol $, instead of admin and!admin.

Text Database exposure

1. The reason of the loophole:

As mentioned earlier, because the text database has great flexibility, there is no need for any external support. Plus, PHP has a very strong ability to handle files, so the text database is widely used in PHP scripts. There are even a few good forum programs that use a text database. But there is a loss, the text database security is also lower than other databases.

2. Vulnerability Resolution:

The text database, as a normal file, can be downloaded, just like an MDB. So we need to protect the text database by protecting the MDB. Change the suffix name of the text database to. Php. And joins in the first row of the database. The text database acts as a PHP file and exits execution on the first line. This is to return an empty page to protect the text database.

Error path Disclosure

1. The reason of the loophole:

When PHP encounters an error, it gives the location, number of rows, and reasons for the error script, for example:

Notice:use of undefined constant test-assumed ' test ' in D:\interpub\bigfly\test.php on line 3

A lot of people say it's not a big deal. But the consequences of revealing the actual path are unthinkable, and for some intruders, this information is very important, and in fact there are many servers that are now in question.

Some network management simply put the PHP configuration file display_errors set to off to solve, but I think this method is too negative. There are times when we really need PHP to return the wrong information for debugging. And you may need to give the user an account when you make an error, or even navigate to another page.

2. Vulnerability Resolution:

PHP provides a functional function of custom error handling handles Set_error_handler () from 4.1.0, but very few scripting people know. In a number of PHP forums, I've only seen a handful of them deal with this situation. The use of Set_error_handler is as follows:

String Set_error_handler (callback Error_Handler [, int error_types])

Now we're going to filter out the actual path with custom error handling.

Copy Code code as follows:

Admin for Administrator's identity, true to administrator.
Custom error-handling functions must have these 4 input variables $errno, $errstr, $errfile, $errline, otherwise invalid.
function My_error_handler ($errno, $errstr, $errfile, $errline)
{
Filter the actual path if it is not an administrator
if (!admin)
{
$errfile =str_replace (GETCWD (), "", $errfile);
$errstr =str_replace (GETCWD (), "", $errstr);
}

Switch ($errno)
{
Case E_ERROR:
echo "ERROR: [ID $errno] $errstr (line: $errline of $errfile)
\ n ";
Echo program has stopped running, please contact the administrator. ";
Exit script when error level errors are encountered
Exit
Break
Case e_warning:
echo "WARNING: [ID $errno] $errstr (line: $errline of $errfile)
\ n ";
Break
Default
Do not show notice-level errors
Break
}
}

Set error handling to My_error_handler function
Set_error_handler ("My_error_handler");
...


In this way, it can be a good solution to the contradictions of security and debugging convenience. And you can also spend some thought, make the error hint more beautiful to match the website style. But note that two points are:

(1) E_error, E_parse, E_core_error, e_core_warning, E_compile_error, e_compile_warning will not be handled by this handle, which will be displayed in the most original way. However, these errors are either compiled or the PHP kernel fails, which is not normally the case.

(2) after using Set_error_handler (), error_reporting () will be invalidated. That is, all errors (except those mentioned above) will be handed to the custom function for processing.
Other information about Set_error_handler (), you can refer to the official PHP manual.

Post vulnerability

1. The reason of the loophole:

As I've said before, it's a bad habit to rely on register_globals to register variables. In some of the message and forum programs, but also to strictly check the way to get the page and the time interval to submit. To prevent the drip-posting and external submissions. Let's take a look at the following code for this program:

Copy Code code as follows:

...
$text 1=flt_tags ($text 1);
$text 2=flt_tags ($text 2);
$text 3=flt_tags ($text 3);

$FD =fopen ("data.php", "a");
Fwrite ($FD, "\r\n$text1&line; $text 2&line; $text 3");
Fclose ($FD);


Obviously, if we submit the URL "post.php?text1=testhaha&text2=testhaha&text3= testhaha". The data will be written to the file normally. This program does not detect the source of the variable and how the browser obtains the page. If we repeat this page repeatedly, we will have a flood effect. Now there are some software use this loophole to send ads in the forum or message book, this is shameful behavior (my friend's message in 1 weeks was filled with more than 10 pages, helpless).

2. Vulnerability Resolution:

Before the data processing and saving, first judge the browser to obtain page mode. Use the $_server["request_method" variable to get the browser's way to get the page. Check to see if it is "POST". Use the session in the script to record whether the user submits the data through the normal path (that is, the page that fills in the submission). or use $_server ["http_referer"] to detect, but this is not recommended. Because some browsers do not have referer set, some firewalls will also block referer. In addition, we also need to check the content of the submission to see if there are duplicate content in the database. Take the message as an example, use the session to determine:
To fill in the browsing content of the page, we at the end of the plus:

$_session["Allowgbookpost"]=time (); Time to fill in the registration

In receiving the message data and save the page we in the data processing before we also use the session to do the following processing:

Copy Code code as follows:

if (Strtoupper ($_server["Request_method"])!= "POST") {die ("error: do not submit externally.") "); } Check if the page Get method is post
if (!isset ($_session["Allowgbookpost")) or (Time ()-$_session["Allowgbookpost"] <)) {die ("error: do not submit externally.") "); } Check the time when the message is filled in
if (Isset ($_session["Gbookposttime")) and (Time ()-$_session["Gbookposttime"] <)) {die ("error: Two submissions are not less than 2 minutes apart." "); } Check the message interval

Unset ($_session["Allowgbookpost"]); Log off the Allowgbookpost variable to prevent multiple submissions from entering the fill page at a time
$_session["Gbookposttime"]=time (); Register time to send messages to prevent flooding or malicious attacks
...


Data processing and preservation

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.