When doing web development, we often do code reviews. Many times, we will randomly check some core functions or logic where loopholes often appear. As the technical team grows, the team members’ skills become increasingly mature. Common fool-type SQL injection vulnerabilities and XSS vulnerabilities. There will be fewer and fewer, but we will also find some emerging covert vulnerabilities that occasionally appear. These vulnerabilities mostly come from developers' insufficient design of a function or common module functions, leaving problems left behind. In the past, we were able to complete some functional modules, but now the requirement is to complete the modules in a safe and correct way. Next, I will share some common functional modules that cause vulnerabilities due to design reasons. Next, let’s first look at the file-reading function vulnerability.
Let’s first look at the following piece of code, which contains different files through the user input of different directories
<?php ///读取模块名称 $mod = isset($_GET['m'])?trim($_GET['m']):'index'; ///过滤目录名称不让跳转到上级目录 <strong><span style="text-decoration: underline;">$mod = str_replace("..",".",$mod);</span> ///得到文件 <strong><span style="text-decoration: underline;">$file = "/home/www/blog/".$mod.".php";</span></strong> ///包含文件 @include($file);Copy after login
This code may have been encountered in the programs made by many friends. It is also easy for newcomers to have such problems. Remember to ask me about the security of your code when I encountered it when I walked through it. Can you do that?
Answer: 1. The ".." directory is replaced, so any .. directory in the module name passed in by the user will be replaced.
2. Construct the spliced file name. There are restrictions on the front directory and extension restrictions on the back. The included files will be limited to this directory
Let’s test what the result will be if $mod passes this value in.
$mod enters ?mod=…%2F…%2F…%2F…%2Fetc%2Fpasswd%00 through construction, we see that the result will be:
Actually include("/etc/passwd") file.
First of all: It is not a good method to use parameter filtering type to limit user input. The general rule is: If it can be detected, do not replace it As long as the test fails, pass directly! This is one of our principles. There are countless filtering failures. Let’s take a look at the actual process.
1. Enter “…/…/…/” by replacing “..” with “.”
2. The result is "../../../" and it becomes this
Some friends will ask, would it be better if I just replace it with spaces? It can indeed be replaced in this one. But it doesn’t mean that you can replace everything with spaces in the future. Let’s take another example. For example: someone replaced the javascript in the string. The code is as follows:
……
$msg = str_replace(“javascript”,””,$msg);
It seems that javascript will no longer appear, but if you enter: jjavascriptavascript to replace, it will replace the middle one when it becomes empty. The "j" in front and the following one will form a new javascript.
Secondly: Let’s see how to escape the .php restrictions behind it. The parameters entered by the user are: "etc/passwd". The characters are very special. After a connection, the file name becomes "...etc/passwd.php". When you print out the variable, it is still correct. However, if a section is put into the file read and write operation method, it will be automatically truncated later. The operating system will only read the etc/passwd file. "" will appear in all file system read and write file variables. will be handled the same way. This C language is related to complete markup as a string.
Through the above analysis, everyone found that when doing file type operations, large loopholes will occur if you are not careful. And this vulnerability may cause a series of security issues.
At this point, some people may be thinking about this. When doing file reading and writing operations, if there are variables in the path, what should I do? Some people may say, is it possible to replace it? "Yes", but this replacement method is not strict and will cause many problems. Moreover, for first-time writers, it is difficult to avoid it. Doing the right thing and choosing the right method will prevent problems from arising. Here, I suggest: Make whitelist restrictions on variables.
For example:
$mod = isset($_GET['m'])?trim($_GET['m']):'index'; ///After reading the module name
If the mod variable value range is an enumeration type then:
if(!in_array($mod,array(‘user’,’index’,’add’,’edit’))) exit(‘err!!!’);
$mod is completely limited, it can only be in this array, that’s cruel! ! ! !
Through the example just now, we know that if it is an enumeration type, just put the value directly into the list. However, sometimes, this is not enough. We have another whitelist restriction method. Just limit the character range
For example:
$mod = isset($_GET['m'])?trim($_GET['m']):'index'; ///After reading the module name
I only know that $mod is a directory name. For general sites, it is letters plus numbers and underscores.
if(!preg_match(“/^w+$/”,$mod)) exit(‘err!!!’);
The characters can only be: [A-Za-z0-9_]. Ruthless enough! ! !
Summary: Have you discovered that the whitelist restriction method is actually very simple to implement? If you know what is required in that place, then you must check the input. Moreover, it is much simpler to detect what you already know than to replace those unknown characters. Okay, let’s stop here first. The correct way to solve the problem will make the file simpler and safer! ! Welcome to communicate!