This article provides a detailed analysis of PHP code review. For more information, see
Overview
Code review is a systematic check of the application source code. It aims to find and fix some vulnerabilities or program logic errors in the application development stage, so as to prevent the illegal exploitation of program vulnerabilities from bringing unnecessary risks to the enterprise.
Code review is not a simple code check. the reason for reviewing the code is to ensure that the code can be securely protected by sufficient information and resources, therefore, it is very important to be familiar with the business process of the entire application to control potential risks.
Reviewers can use questions similar to the following to interview developers to collect application information.
What types of sensitive information does an application contain and how does the application protect it?
Does an application provide internal services or external services? Who will use it? are they all trusted users?
Where is the application deployed?
What is the importance of applications for enterprises?
The best way is to make a checklist for developers to fill in. Checklist can intuitively reflect application information and coding security done by developers. it should cover modules that may have severe vulnerabilities, such: data verification, identity authentication, session management, authorization, encryption, error processing, logs, security configuration, and network architecture.
Input verification and output display
Most vulnerabilities are caused by the absence of security verification on the input data or the absence of security processing on the output data. the strict data verification method is: precise data matching.
Accept data from the whitelist
Reject blacklist data
Encode the data that matches the blacklist
In PHP, the list of variables that users can enter is as follows:
$ _ SERVER
$ _ GET
$ _ POST
$ _ COOKIE
$ _ REQUEST
$ _ FILES
$ _ ENV
$ _ HTTP_COOKIE_VARS
$ _ HTTP_ENV_VARS
$ _ HTTP_GET_VARS
$ _ HTTP_POST_FILES
$ _ HTTP_POST_VARS
$ _ HTTP_SERVER_VARS
We should check these input variables
Command injection
Security threats
Command injection attacks modify the dynamically generated content of a webpage by inputting HTML code into an input mechanism (for example, a table domain that lacks valid verification restrictions, this may cause malicious commands to control users' computers and their networks. The following functions can be used to execute system commands in PHP: system, exec, passthru, '', shell_exec, popen, proc_open, and pcntl_exec. we can search for these functions in all program files, determine whether the function parameters are changed due to external submissions and check whether these parameters have been safely processed.
Sample code
Example 1:
The code is as follows:
// Ex1.php
$ Dir = $ _ GET ["dir"];
If (isset ($ dir ))
{
Echo"
";
system("ls -al".$dir);
echo "
";
}
?>
We submit
The code is as follows:
Http: // localhost/ex1.php? Dir = | cat/etc/passwd
After submission, the command becomes
The code is as follows:
System ("ls-al | cat/etc/passwd ");
Defense methods
1. try not to execute external commands
2. use a user-defined function or function library to replace the functions of external commands
3. use the escapeshellarg function to process command parameters
4. use safe_mode_exec_dir to specify the path of the executable file
The esacpeshellarg function will escape any character that causes the parameter or command end. replace the single quotation mark (') with "\", double quotation mark ("") with "\" ", replace semicolon ";" with "\;", and use safe_mode_exec_dir to specify the path of the executable file. you can put the commands you want to use into this path in advance.
The code is as follows:
Safe_mode = On
Safe_mode_exec_di r =/usr/local/php/bin/
Cross Site Scripting)
Security threats
Cross Site Script (XSS), a Cross-Site scripting threat. Attackers can use the application's dynamic data display function to embed malicious code into html pages. When a user browses this page, the malicious code embedded in html will be
Attackers can control the user's browser for special purposes. Output functions are often used: echo, print, printf, vprintf, <% = $ test %>
There are three types of XSS attacks:
(1) reflected cross-site scripting attacks
Through social engineering, attackers can send a URL connection to the user to open the page. when the user opens the page, the browser will execute malicious scripts embedded in the page.
(2) storage-type XSS attacks
Attackers can use the data entry or modification function provided by web applications to store data to servers or user cookies. when other users browse the pages that display the data, the browser executes malicious scripts embedded in the page. All viewers will be attacked.
(3) DOM Cross-site attack
Because a piece of JavaScript code is defined in the html page, an html code is displayed based on the user input. attackers can insert a malicious script during the input and execute the malicious script during the display. The difference between DOM Cross-site attack and the above two cross-site attacks is that DOM Cross-site is the output of pure page scripts. only JAVASCRIPT can be used for defense.
Malicious attackers can use cross-site scripting:
(1) steal user cookies and forge user identities to log on.
(2) the browser is forced to perform a page operation and initiate a request to the server as a user to attack the server.
(3) Download the virus Trojan to the viewer's computer based on browser vulnerabilities.
(4) derivative URL jump vulnerability.
(5) publish a phishing page to the official website.
(6) worm attacks
Sample code
"User controllable data" is displayed directly on the html page, which directly leads to cross-site scripting threats.
The code is as follows:
Echo "$ newsname ";
Echo "$ gifname ";
Echo"";
Echo "". htmlentities ($ context )."";
?>
These display methods may cause the user's browser to regard "user controllable data" as JS/VBS script execution, or the page element to be controlled by the HTML code of the page inserted by "user controllable data, this can cause attacks.
Solution
A) before "user controllable data" is displayed in HTML, htmlescape should be escaped.
The code is as follows:
Htmlspecialchars ($ outputString, ENT_QUOTES );
Html escape should be escaped according to the following list:
The code is as follows:
& --> &
<--> <
> -->
"-->"
'-->'
B) javascript escape is required for "User controllable data" output in javascript.
Escape characters include:
The code is as follows:
/--> \/
'--> \'
"--> \"
\ --> \\
C) perform security filtering on "User controllable data" output to rich text to prevent script code in the rich text editor.
SQL Injection)
Security threats
When an application concatenates the content entered by the user into an SQL statement and submits the content to the database for execution, SQL injection is threatened. Because user input is also part of SQL statements, attackers can use this part to control the content, inject their own defined statements, and change the SQL statement execution logic, allows the database to execute any commands required by itself. By controlling some SQL statements, attackers can query any data they need in the database. using some features of the database, attackers can directly obtain the system permissions of the database server. Originally, SQL injection attacks require attackers to be familiar with SQL statements, so they have certain technical requirements. However, a large number of SQL injection and exploitation tools have emerged a few years ago, allowing any attacker to click a few mouse clicks to achieve the attack effect. This has greatly increased the threat of SQL injection.
General steps for SQL injection attacks:
1. attackers can access websites with SQL injection vulnerabilities to find injection points.
2. attackers construct injection statements, which are combined with the SQL statements in the program to generate new SQL statements.
3. the new SQL statement is submitted to the database for processing.
4. the database executes new SQL statements, triggering SQL injection attacks.
Sample code
If the input check is insufficient, the SQL statement executes the illegal data submitted by the user as part of the statement.
Example:
The code is as follows:
$ Id = $ _ GET ['id'];
$ Name = $ _ GET ['name'];
$ SQL = "select * from news where 'id' = $ id and 'username' = '$ name '";
?>
Solution
A) security configuration and encoding method. PHP configuration options are specified in the php. ini file. The following configuration methods can enhance the security of php and prevent the application from being attacked by SQL injection.
1) safe_mode = onPHP will check whether the owner of the current script matches the owner of the operated file through the file function or its directory, illegal operation if the current script owner does not match the file operation owner
2) magic_quotes_gpc = on/off. if this option is activated, any single quotation marks, double quotation marks, backslash, and empty characters contained in the request parameters will be automatically escaped with a backslash.
3) magic_quotes_sybase = on/off. if the option is disabled, PHP will use a single quotation mark to escape all single quotes.
Verify numeric variables
$ Id = (int) $ id;
Note: PHP6 has deleted the magic quotes option.
B) use preprocessing to execute SQL statements and bind all the variables in the passed SQL statements. In this way, the variables that the user concatenates, no matter what the content is, will be used as an alternative symbol "?" The database does not
Parses the data spliced by malicious users as part of SQL statements. Example:
The code is as follows:
$ Stmt = mysqli_stmt_init ($ link );
If (mysqli_stmt_prepare ($ stmt, 'Select District FROM City WHERE Name =? '))
{
/* Bind parameters for markers */
Mysqli_stmt_bind_param ($ stmt, "s", $ city );
/* Execute query */
Mysqli_stmt_execute ($ stmt );
/* Bind result variables */
Mysqli_stmt_bind_result ($ stmt, $ district );
/* Fetch value */
Mysqli_stmt_fetch ($ stmt );
Mysqli_stmt_close ($ stmt );
}
/* Close connection */
Mysqli_close ($ link );
File Upload threats)
Security threats
The PHP file Upload vulnerability mainly occurs when the file type is verified and the attack caused by file variables is not handled properly. as a result, the program judgment logic is bypassed, and the attacker uploads the script file to the server for parsing, to obtain the SHELL or Upload
The file is freely copied, and even the script Trojan is uploaded to the web server to directly control the web server.
Sample code
Code used to process a file upload request. this code does not filter file extensions.
The code is as follows:
// OldUpload. php
If (isset ($ upload) & $ myfile! = "None" & check ($ myfile_name )){
Copy ($ myfile, "/var/www/upload/". $ myfile_name );
Echo "file". $ file_name. "uploaded successfully! Click continue Upload ";
Exit;
}
// CheckUpload. php
$ DeniedExtensions = array ('html', 'htm', 'php', 'php2', 'php3', 'php4 ', 'php5', 'Ph
Tml', 'pwm', 'INC', 'asp ', 'aspx', 'ascx', 'JSP ', 'cfm', 'cfc', 'Pl ', 'batt', 'exe ','
Com ', 'dll', 'vbs ', 'js', 'Reg', 'CGI ', 'htaccess', 'assig ');
If ($ checkUpload ($ _ FILE ['myfile'] [name], $ DeniedExtensions) {copy ($ _ FILE ['myfile'] [tmp_name], 'upload /'. $ _ FILE ['myfile'] [name]);
}
?>
File Upload
Solution
To process uploaded files, perform the following checks:
(1) Check whether the filename extension complies with the whitelist specification.
(2) save the file to the server in the form of a random file name.
(3) the uploaded directory script file cannot be executed.
(4) % 00 truncation
(5) for jpg files, you need to read the file content and generate a new jpg file to save it.
Cross-Site Request Forgery (CSRF)
Security threats
Cross-Site Request Forgery (CSRF. When a user browses a webpage, the attacker uses page elements (such as the src of img) to force the victim's browser to send a request to the Web application to change user information. In the case of CSRF attacks, attackers force users to send requests to the server. Therefore, user information is forced to be modified. in more serious cases, worms are exploited.
CSRF attacks can be initiated outside and within the site. To initiate a CSRF attack from a website, you must use the website's services, such as the "custom profile picture" function. a malicious user specifies that the profile picture URL is a link to modify user information, when other logged-on users browse malicious user portraits, the system will automatically send a request to modify the information to this link.
When sending a request outside the site, a malicious user needs to put an htm page that automatically submits and modifies his/her personal information on his/her server, and send the page address to the victim. when the victim opens the page, A request is initiated.
If malicious users can know the URL of a function in the website management background, they can directly attack the administrator and force the administrator to perform operations defined by malicious users.
Sample code
A code without CSRF security defense is as follows:
The code is as follows:
$ User = checkSQL ($ user );
$ Pass = checkSQL ($ pass );
$ SQL = "update UserTB set password = $ user Where user = $ pass ";
Mysqli_stmt_execute ($ SQL );
?>
The code receives the parameter "user, pass" submitted by the user, and then modifies the user's data. Once a user receives a request, the modification is performed.
Code for submitting a form:
The code is as follows:
When the user clicks submit, the modification operation is triggered.
Attack instance
If the code in the "sample code" is a web application on xxx.com, malicious users can construct two HTML pages to attack logon users of xxx.com.
(1) in a.htm, set the width and height to 0 in iframe B .htm.
The code is as follows:
</Frame> <BR> when an attack occurs, the victim cannot see the successful submission result page. <BR> (2) the B .htm page contains a form and a script. the script automatically submits the form when the page is loaded. <BR> <U> </U> code: <BR> script <BR> document. getElementById ("modify "). submit (); <BR> script <BR> (3) attackers only need to place the.htm page on their web server and send it to the login user. After opening a.htm, the user will automatically submit a form and send it to the web application with the CSRF vulnerability under xxx.com. Therefore, the user's information is forced to be modified. </P> <STRONG> solution <BR> </STRONG> the principle of CSRF defense is to generate a random token during user logon, store it in a cookie (by default, it can also be stored in a session). when a form is generated, a hidden field is generated, the value of the hidden field is equal to the value of the token <BR>. If the user submits this form, the user can determine whether the TOKEN value of the hidden domain is consistent with the TOKEN value in the user COOKIE in the web application that receives the user request. if the value is inconsistent or does not exist, <BR> The attack is broken into a CSRF attack. Attackers cannot predict the random TOKEN value generated when each user logs on, so they cannot forge this parameter. <Br> <STRONG> FAQ <BR> </STRONG> (1) why not directly verify referer? <BR> because csrf is also sent from the station and referer can be tampered with, it is unreliable data <BR> (2) if xss attacks occur first, what can an attacker do if he can get the token of the user page? <BR> no solution. please take xss protection first. <BR> <STRONG> File inclusion <BR> </STRONG> PHP can output the number of letters contained in the current file package: include, include_once, require, require_once, show_source, highlight_file, readfile, file_get_contents, fopen, file <BR> <STRONG> defense methods: <BR> </STRONG> precisely matches the input data, for example, determining the language en based on the value of the variable. php, cn. php, then the two files are placed in the same directory 'language /'. $ _ POST ['Lang ']. '. php ', <BR> check whether the submitted data is en or cn is the strictest. check whether it only contains letters. filter /,... <BR> <STRONG> HTTP response splitting <BR> </STRONG> in PHP, the header function and $ _ SERVER variable can be used to split an HTTP response. Note that PHP later versions will disable line breaks in the HTTP header. you can skip this test directly. <BR> <STRONG> prevention method: <BR> exact match of input data <BR> </STRONG> If \ r or \ n is included in the input, directly reject <BR> <STRONG> Variable overwrite <BR> </STRONG> PHP variable overwrite may occur in the following situations: <BR> <STRONG> Traverse initialization variables <BR> </STRONG> Example: <BR> <U> </U> the code is as follows: <BR> foreach ($ _ GET as $ key => $ value) <BR >$ $ key = $ value; <BR> function override variable: when parse_str, mb_parse_str, import_request_variables, and Register_globals = ON, variables submitted in GET mode will directly overwrite <BR> <STRONG> defense methods: <BR> </STRONG> set Register_globals = OFF <BR> do not use these functions to obtain variables <BR> <STRONG> Dynamic functions <BR> </STRONG> when using dynamic functions, if you have control over variables, attackers can execute arbitrary functions. <BR> Example: <BR> <U> </U> the code is as follows: <BR> <? Php <BR> $ myfunc =$ _ GET ['myfunc']; <BR> $ myfunc (); <BR >?> <BR> <STRONG> Defense method: <BR> </STRONG> do not use functions like this <BR> session Security <BR> HTTPOnly setting <BR> session. when cookie_httponly = ON, client scripts (such as JavaScript) cannot access the cookie. enabling this command can effectively prevent session IDs from being hijacked by XSS attacks <BR> domain settings <BR> Check the session. whether cookie_domain only contains this domain. if it is a parent domain, other subdomains can obtain cookies of this domain <BR> path settings <BR> Check session. cookie_path: if the website is applied to/app, the path must be set to/app/to ensure security <BR> cookie duration <BR> Check session. cookie_lifetime: if the time setting process is too long, even if the user closes the browser, attackers may endanger account security <BR> secur E setting <BR> If HTTPS is used, set the session. cookie_secure = ON, make sure to use HTTPS to transmit cookies <BR> session fixed <BR> if the permission level changes (for example, after verifying the user name and password, the common user is promoted to the administrator ), we should modify the session ID to be re-generated, otherwise the program will face the risk of fixed session attacks. </P> <STRONG> encryption <BR> </STRONG> plaintext storage password <BR> The plaintext storage password seriously threatens users, applications, and systems. security. <BR> weak password encryption <BR> use an easy-to-crack encryption algorithm, MD5 encryption can be used to crack websites. <BR> reference solution <BR> <U> </U> the code is as follows: <BR> md5 ($ password ). $ salt) <BR> The password is stored in files accessible to attackers. <BR> For example, the password is stored in txt, ini, conf, inc, xml, and other files, alternatively, you can directly write it in the HTML comment </P> <STRONG> authentication and authorization <BR> user authentication <BR> </STRONG> to check the location where the code performs user authentication, whether authentication can be bypassed. for example, form injection may exist in the login code. <BR> check whether the logon code uses a verification code, prevention of brute-force cracking <BR> unauthenticated calls to functions or files <br> some management pages prohibit access by common users, sometimes developers forget to perform permission verification on these files, resulting in a vulnerability <BR> some pages use the parameter call function without permission verification, such as index. php? Action = upload <BR> password hardcoded <br> some programs directly write the database linked account and password to the database linked function. <BR> random function <BR> rand () VS mt_rand () <BR> The maximum random number of rand () is 32767. When rand is used to process sessions, attackers can easily crack sessions, mt_rand () is recommended (). <BR> sample code <BR> <U> </U> the code is as follows: <BR> <? Php <BR> // on windows <BR> print mt_getrandmax (); // 2147483647 <BR> print getrandmax (); // 32767 <BR >?> <BR> we can see that the maximum random number of rand () is 32767, which is easily cracked by us. <BR> <U> </U> the code is as follows: <BR> <? Php <BR> $ a = md5 (rand (); <BR> for ($ I = 0; $ I <= 32767; $ I ++) {<BR> if (md5 ($ I) ==$ a) {<BR> print $ I. "--> OK !! <Br> "; exit; <BR >}else {print $ I." <br> ";}< BR >}< BR >?> <BR> when our program uses rand to process sessions, attackers can easily crack your sessions. However, mt_rand is difficult to crack. </P>