Home  >  Article  >  Backend Development  >  Analysis of the causes of PHP program vulnerabilities and explanation of prevention methods_PHP tutorial

Analysis of the causes of PHP program vulnerabilities and explanation of prevention methods_PHP tutorial

WBOY
WBOYOriginal
2016-07-13 10:37:09789browse

Abusing include

1. Cause of vulnerability:

Include is the most commonly used function in writing PHP websites and supports relative paths. There are many PHP scripts that directly use an input variable as an Include parameter, causing vulnerabilities such as arbitrary script reference and absolute path leakage. Look at the following code:

...
$includepage=$_GET["includepage"];
include($includepage);
...

Obviously, we only need to submit different Includepage variables to get the desired page. If you submit a page that does not exist, you can cause the PHP script to error and leak the actual absolute path (the solution to this problem is explained in the following article).

2. Vulnerability resolution:

The solution to this vulnerability is very simple, which is to first determine whether the page exists and then include it. Or more strictly, use an array to specify the files that can be included. Look at the following code:

Copy code The code is as follows:

$pagelist=array("test1.php","test2. php","test3.php"); //Here are the files that can be included
if(isset($_GET["includepage"])) //Determine whether there is $includepage
{
$ includepage=$_GET["includepage"];
foreach($pagelist as $prepage)
{
if($includepage==$prepage) //Check whether the file is in the allowed list
{
include($prepage);
$checkfind=true;
break;
}
}
if($checkfind==true){ unset($checkfind); }
else{ die("Invalid reference page!"); }
}

This can solve the problem well.

Tips: Functions with this problem include: require(), require_once(), include_once(), readfile(), etc. Please pay attention when writing.

Input variables are not filtered

1. Cause of vulnerability:

This vulnerability has long appeared in ASP, causing countless injection vulnerabilities at that time. But because PHP had a small influence at the time, not many people could pay attention to this. For PHP, this vulnerability has a greater impact than ASP because more PHP scripts use text databases. Of course, there is also the problem of SQL statement injection. To give a more classic example, the first is the database:

Copy code The code is as follows:

$id=$_GET[ "id"];

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


It is obvious here that we can use injection to obtain other contents of the database. I won’t describe it in detail here. Just like ASP injection, you can take a look at previous black defenses. Then we look at the problem of text database:
Copy code The code is as follows:

$text1=$_POST["text1"] ;
$text2=$_POST["text2"];
$text3=$_POST["text3"];

$fd=fopen("test.php","a");
fwrite($fd,"rn$text1&line;$text2&line;$text3");
fclose($fd);


The text vulnerability can be said to be even more serious. If we insert a small piece of PHP code into the submitted variable, we can turn this text database test.php into a PHP backdoor. Even inserting the upload code allows us to upload a complete PHP backdoor. Then increase the privileges and the server is yours.

2. Vulnerability resolution:

The solution to this vulnerability is actually very simple, which is to strictly filter all submitted variables. Replace some sensitive characters. We can replace the content of HTML with the help of the htmlspecialchars() function provided by PHP. Here is an example:

Copy code The code is as follows:

//Construct filter function
function flt_tags($text)
{
$badwords=array("fuck","fuck"); //Word filter list
$ text=rtrim($text);
foreach($badwords as $badword) //Word filtering is done 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

$text=str_replace("r"," ",$text);
$text=str_replace("n","",$text);
$text=str_replace("&line;" ,"│",$text); //Replace the text database delimiter "&line;" with the full-width "│"
$text=preg_replace("/s{ 2 }/"," ",$text); //Space replacement China Network Management Alliance
$text=preg_replace("/t/"," ",$text); // Still space replacement
if(get_magic_quotes_gpc()){ $text=stripslashes($text ); } //If magic_quotes is turned on, replace '
return $text;
}

$text1=$_POST["text1"];
$text2=$_POST["text2"];
$text3=$_POST["text3"];

//Filter all inputs
$text1=flt_tags($text1);
$text2=flt_tags($text2);
$text3=flt_tags($text3);

$fd=fopen("test.php","a");
fwrite($fd,"rn$text1&line;$text2&line;$text3");
fclose($fd);


After some replacement and filtering, you can safely write the data into text or database.

The administrator’s judgment is incomplete

1. Cause of vulnerability:

We use PHP to write scripts, which usually involve administrator permission issues. Some scripts only make a "yes" judgment on administrator permissions, but often ignore the "no" judgment. When register_globals is turned on in the PHP configuration file (it is turned off by default in versions after 4.2.0, but many people turn it on for convenience, which is extremely dangerous behavior), there will be situations where the submitted variable impersonates the administrator. Let’s take a look at the example code:

Copy code The code is as follows:

$cookiesign="admincookiesign"; //Determine whether Admin's cookie variable
$adminsign=$_COOKIE["sign"]; //Get the user's cookie variable

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

if($admin){ echo "Now the administrator status."; }


It seems very safe, haha. Now we assume that register_globals is turned on in the PHP configuration file. We submitted such an address "test.php? admin=true", have you seen the result? Although we do not have the correct cookie, because register_globals is turned on, the admin variable we submitted is automatically registered as true. Moreover, the script lacks a "no" judgment, which allows us to successfully obtain administrator permissions through admin=true. This problem exists on most websites and forums.

2. Vulnerability resolution:

To solve this problem, we only need to add a "no" judgment to the administrator in the script. We still assume that register_globals is turned on in the PHP configuration file. Take a look at the code:

Copy code The code is as follows:

$cookiesign="admincookiesign"; // Determine whether it is Admin cookie variable
$adminsign=$_COOKIE["sign"]; //Get the user's cookie variable

if($adminsign==$cookiesign)
{
$admin=true;
}
else
{
$admin=false;
}
if($admin){ echo "Now the administrator status."; }


In this way, even if the attacker submits the admin=true variable without the correct cookie, the script will be used in the future $admin will also be set to False in the judgment. This solves part of the problem. However, since $admin is a variable, if a loophole occurs in other script references in the future and $admin is reassigned, a new crisis will occur. Therefore, we should use constants to store the determination of administrator permissions. Use the Define() statement to define an admin constant to record the administrator's permissions. If it is reassigned after this, an error will occur, thus achieving the purpose of protection. Look at the following code:
Copy code The code is as follows:

$cookiesign="admincookiesign"; // Determine whether Admin's cookie Variable
$adminsign=$_COOKIE["sign"]; //Get the user's cookie variable

if($adminsign==$cookiesign)
{
define(admin,true);
}
else
{
define(admin,false);
}
if(admin){ echo "Now the administrator status."; }


It is worth noting that we use the Define statement, so when calling the Admin constant, do not habitually add the variable symbol $ in front of it, but use Admin and !admin.

Text database exposed

1. Cause of vulnerability:

As mentioned earlier, due to the great flexibility of text databases, no external support is required. In addition, PHP has very strong file processing capabilities, so text databases are widely used in PHP scripts. There are even several good forum programs that use text databases. But there are gains and losses, and the security of text databases is lower than other databases.

2. Vulnerability resolution:

The text database acts as an ordinary file and can be downloaded, just like an MDB. So we need to use the same method to protect MDB to protect the text database. Change the suffix name of the text database to .PHP. And join in the first row of the database. This way the text database will be treated as a PHP file and execution will exit on the first line. That is, an empty page is returned to achieve the purpose of protecting the text database.

Error path leaked

1. Cause of vulnerability:

When PHP encounters an error, it will give the location, line number and reason of the error script, for example:

Notice: Use of undefined constant test - assumed 'test' in D:interpubbigflytest.php on line 3

A lot of people say it’s not a big deal. But the consequences of leaking the actual path are unimaginable. For some intruders, this information is very important. In fact, many servers now have this problem.

Some network administrators simply set display_errors in the PHP configuration file to Off to solve the problem, but I think this method is too negative. Sometimes, we really need PHP to return error information for debugging. And when something goes wrong, you may also need to give the user an explanation or even navigate to another page.

2. Vulnerability resolution:

PHP has provided the function set_error_handler() to customize error handling handles since 4.1.0, but few script writers know about it. Among the many PHP forums, I have seen only a few handle this situation. The usage of set_error_handler is as follows:

string set_error_handler ( callback error_handler [, int error_types])

Now we use custom error handling to filter out the actual paths.

Copy code The code is as follows:

//admin is the identity determination of the administrator, true is the administrator.
//The custom error handling function must have these four input variables $errno, $errstr, $errfile, $errline, otherwise it will be invalid.
function my_error_handler($errno,$errstr,$errfile,$errline)
{
//If you are not an administrator, filter the actual path
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 "The program has stopped running, please contact the administrator.";
//Exit the script when encountering an Error level error
exit;
break;
case E_WARNING:
echo "WARNING: [ID $errno] $errstr (Line: $errline of $errfile)
n";
break;
default:
//Do not display Notice level errors
break;
}
}

//Set error handling to the my_error_handler function
set_error_handler("my_error_handler");


In this way, the contradiction between security and debugging convenience can be well solved . And you can also put some thought into making the error message more beautiful to match the style of the website. But pay attention to two points:

(1) E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, and E_COMPILE_WARNING will not be processed by this handle, that is, they will be displayed in the most original way. However, these errors are caused by compilation or PHP kernel errors and will not occur under normal circumstances.

(2) After using set_error_handler(), error_reporting () will be invalid. That is, all errors (except the above errors) will be handed over to the custom function for processing.
For other information about set_error_handler(), you can refer to the official manual of PHP.

POST vulnerability

1. Cause of vulnerability:

As mentioned before, relying on register_globals to register variables is a bad habit. In some guestbook and forum programs, it is even more necessary to strictly check the method of obtaining pages and the time interval between submissions. To prevent spam posts and external submissions. Let’s take a look at the code of a guestbook program below:

Copy the code The code is as follows:

...
$text1=flt_tags($text1);
$text2=flt_tags($text2);
$text3=flt_tags($text3);

$fd=fopen("data.php","a");
fwrite($fd,"rn$text1&line;$text2&line;$text3");
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 variables and how the browser obtained the page. If we submit multiple submissions to this page, it will cause a flood. There are also some softwares that take advantage of this vulnerability to post advertisements on forums or guestbooks, which is a shameful behavior (my friend's guestbook was flooded with more than 10 pages in one week, which was helpless).

2. Vulnerability resolution:

Before processing and saving data, first determine how the browser obtains the page. Use the $_SERVER["REQUEST_METHOD"] variable to obtain the browser's method of obtaining the page. Check if it is "POST". Use session in the script to record whether the user submits data through normal channels (that is, the page where the submission content is filled in). Or use $_SERVER["HTTP_REFERER"] to detect this, but this is not recommended. Because some browsers do not set REFERER, some firewalls will also block REFERER. In addition, we also need to check the submitted content to see if there is duplicate content in the database. Take the guestbook as an example, use Session to make the determination:
In the page where you fill in the browsing content, we add at the front end:

$_SESSION["allowgbookpost"]=time(); //The time when filling in the registration

In the page that accepts message data and saves it, we also use Session to perform the following processing before data processing:

Copy code The code is as follows:

if(strtoupper($_SERVER["REQUEST_METHOD"])!="POST"){ die("Error: Do not submit externally."); } //Check whether the page acquisition method is POST
if(!isset($_SESSION["allowgbookpost"]) or (time()-$_SESSION["allowgbookpost"] < 10)){ die("Error: Do not submit externally."); } //Check the time when the message was filled in
if(isset($_SESSION["gbookposttime"]) and (time()-$_SESSION["gbookposttime"] < 120)){ die("Error: twice The interval between submitting messages shall not be less than 2 minutes. "); } //Check the message interval

unset($_SESSION["allowgbookpost"]); //Unregister the allowgbookpost variable to prevent multiple submissions from entering the fill-in page at one time
$_SESSION["gbookposttime"]=time(); //Register to send messages time to prevent spamming or malicious attacks
...


Data processing and storage

www.bkjia.comtruehttp: //www.bkjia.com/PHPjc/736794.htmlTechArticleAbusing include 1. Reason for the vulnerability: Include is the most commonly used function in writing PHP websites and supports relative paths. There are many PHP scripts that directly use an input variable as an Include parameter, causing any...
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn