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:
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:
$query="SELECT * FROM my_table where id='".$id."'"; //A very classic SQL injection vulnerability
$result=mysql_query($query);
$fd=fopen("test.php","a");
fwrite($fd,"rn$text1&line;$text2&line;$text3");
fclose($fd);
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:
$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);
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:
if($adminsign==$cookiesign)
{
$admin=true;
}
if($admin){ echo "Now the administrator status."; }
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:
if($adminsign==$cookiesign)
{
$admin=true;
}
else
{
$admin=false;
}
if($admin){ echo "Now the administrator status."; }
if($adminsign==$cookiesign)
{
define(admin,true);
}
else
{
define(admin,false);
}
if(admin){ echo "Now the administrator status."; }
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.
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");
…
(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:
$fd=fopen("data.php","a");
fwrite($fd,"rn$text1&line;$text2&line;$text3");
fclose($fd);
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:
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
...