Aquaboutic | Focus Security Research | Vulnerability Exploit | POC


cheat sheet for php security

Posted by ulberg at 2020-02-17

This page is intended to provide developers and administrators with basic tips about PHP security. Note that only the tips described in this page may not be sufficient to ensure web application security.

PHP summary

PHP is the most commonly used server-side programming language, according to w3teches, a 81.8% web server.

The open source technology PHP is unique in terms of both language and web frameworks. Like other web languages, there are large communities such as libraries that contribute to programming security in PHP. In order to secure the security of the PHP site, you must consider all three aspects (language, framework, Library).

PHP is a growing language rather than a carefully designed language, so it tends to easily describe a secure PHP application. For safe use of PHP, you need to know all of its potential dangers.

Language issues

Weak type

PHP is loose on typing. That is, PHP will autoconvert the incorrect type of data to the appropriate type. This feature often covers developers' errors and inappropriate data insertion, which leads to vulnerabilities.

Use functions and operators without implicit conversion. For example, use = = instead of = =. Not all operators have a strict version of type (greater or smaller). Also, in many built-in functions (such as in array), a relatively weak type comparison function is used by default. This makes it difficult to write the appropriate code.

== === in_array == === in_array

Exception handling and error handling

Almost all PHP built-in functions and many PHP libraries do not use exceptions, and instead report an error with another method (such as notification). Therefore, it is possible to continue execution even with the defective code. As a result, many bugs are hidden. In many other languages competing with PHP and most of the high-level languages, the program stops execution because of developer mistakes or an error prone error that the developer has failed to run. This is the safest response.

Look at the following code: This code restricts access to certain functions using a database query to determine if the username is contained in the blacklist.

This code can cause various runtime errors. For example, a database connection fails due to a password error or a server stop, or a client opened connection may then be closed by the server. In this case, the mysqli function group raises a warning or notification, but does not throw an exception or fatal error. That is, the code continues as it is. The variable $row is null. PHP evaluates $row [0] as null and evaluates (int) $row [0] to 0 because of its weak typing. Finally, the access function function returns true, allowing access to all users regardless of whether it is listed in the blacklist.

mysqli_ $row NULL $row[0] NULL (int)$row[0] can_access_feature true mysqli_ $row NULL $row[0] NULL (int)$row[0] can_access_feature true

If you want to use these native database APIs, you must add an error check to each location. However, it is likely to be omitted because it requires extra work and is not safe by default. Many code descriptions are also required. For this reason, it is recommended that you always use the PHP data object (PDO) to access the database and specify the errmode Waring or errmode exception flags, unless you have a clear reason that you have to adopt careful error checking with native drivers .

In many cases, it is best to use the error reporting function to set the error reporting level as high as possible. Never suppress an error message. Be sure to write a more robust code according to the warning.


PHP code behavior is usually dependent on many configuration settings. This includes changes to basic behavior, such as error handling. It is therefore difficult to write code that works correctly in all environments. Since the assumptions and requirements for these settings vary depending on the library, it is difficult to use third party code properly. Some are described in the following settings.

Useless built-in functions

PHP has many built-in built-in functions (for example, addslashes, MySQL escape, mysql, and MySQL), many of which are buggy and are not really useful for dealing with security problems. Some of these functions have been deprecated and removed, but this will take a long time from the lower compatibility policy.

addslashes mysql_escape_string mysql_real_escape_string addslashes mysql_escape_string mysql_real_escape_string

PHP has a data structure called array, which is widely used in PHP code and internally, which is confusing with array and dictionary. Due to this confusion, even experienced PHP developers will bring serious security vulnerabilities, such as drupal sa-core-2014-005 (see patches).

Framework issues

URL routing

The URL routing mechanism built in PHP uses files that end with ". PHP" in the directory structure. The following vulnerabilities occur here.

.htaccess .htaccess

Input processing

If the attacker uses the following query string:

$feed nonce array. The StrCmp () The comparison is successful because the type weakness and the = = (equality) operators are used, rather than the = = (equality) operator (since PHP is true in the expression null = = 0). Therefore, the attacker can reset the password without specifying the correct nonce.

$supplied_nonce strcmp() NULL === == NULL == 0 $supplied_nonce strcmp() NULL === == NULL == 0

The same problem may be exploited by problems such as drupal sa-col-2014-005 in conjunction with the confusion of the PHP array data structure. See abuse examples.

Template language

PHP is basically a template language. However, default does not escape HTML. This is a very problematic language for use in web applications. See section XSS below.

Other faults

Another important feature is that web frameworks must be provided, such as the default CSRF mechanism, which is on by default. PHP comes with an elementary web framework, and it is practical enough to create a web site, so many people create a web site without knowledge necessary for CSRF.

Third party PHP code

Because of the above problems, libraries and projects described in PHP are often dangerous. Especially if the appropriate web framework is not used. Don't trust the PHP code found on the web, as you might be hiding a lot of security vulnerabilities even in code that appears to be seemingly harmless.

An incomplete description of PHP code often causes warnings, causing problems. A common solution is to clear all notifications, this is the opposite of the appropriate correspondence (see above) and the code further worsens.

Regular updates in PHP

Be careful to upgrade the PHP distribution on the running server. Every day a new vulnerability has been found and published in PHP. Attackers often utilize these new vulnerabilities on any server.

There are many security options to configure. The following part shows.


Set the PHP code to run using the 'sethandler' directive. In many cases, the 'addander' directive is mistaken. It works, but other files can also be run as PHP code. For example, if the file name "fo.php.txt" is treated as a PHP code, it is likely to be a very serious remote execution vulnerability if this file is not intended to run or is derived from malicious file uploads .

None of the user input results or data that is a by-product must be trusted. You need to verify or filter the data by an appropriate methodology. This is the first time you can see that data is not contaminated.


File upload

The files received from the user will cause various security threats, especially if other users can download it. In particular, the following threat is considered.

Since PHP is designed to be very easy to execute PHP code (just a file with the appropriate extension), PHP site (all sites where PHP is installed) will be able to sanitize the file name when saving the uploaded file Is especially important.

Common errors in processing the $fills array

Code snippets that look similar to the following code are often found on the Internet.

Here, $mimeType is a more appropriately verified file type. This method consumes more of the server's resources, but it can prevent users from sending dangerous files and cheating codes and causing them to be imagined. An image file is usually considered a safe file type.

Using $request

It is strongly recommended not to use $. The reason why this super global variable is not recommended is that not only the post and get data but also the cookie sent by the request is included in this variable. Since all of these data are in one array, it is almost impossible to identify the source of the data. This causes confusion and makes it easier to make mistakes in code. This can lead to security problems.

If you have one SQL injection vulnerability, you will be able to hack the web site. Therefore, any hacker will first attempt to expose SQL injection vulnerabilities. Therefore, modifying SQL injection vulnerabilities is the first step to ensure the safety of PHP based applications. Observe the following rules.

SQL does not bind or interpolate data

Do not use connection to create SQL strings that contain user data.

Do not use interpolation.

Escape is not secure

Escape escape string is not safe. Do not rely on SQL injection.

The reason: if you use MySQL and real escape string in all variables and connect them to a query, it is decided to forget about once. Once in a while. It is impossible for anyone to forget absolutely. You must also use quotes in SQL, but this is an unnatural act if you assume your data as a numeric value. Instead, use the equivalent API or the equivalent API that will always execute the appropriate SQL escapes (most ORM will do this escape and create SQL).

Using a prepared statement

The prepared statement is very secure. In the prepared statement, data is separated from the SQL command. All content entered by the user is considered as data and stored in the table as it is.

See mysqli prepared statements and PDO prepared statements in the PHP documentation.

If the prepared statement does not function

The problem is if you need to create a dynamic query or set a variable that is not supported as a prepared variable, or if the database engine does not support a prepared statement. For example, PDO MySQL does not support. Also, the prepared statement cannot be used for table names or columns in the ` select ` statement. If this is the case, the framework builds the query builder. If the query builder is not available, multiple packages are available from the composer and packagist. Do not use your own.


ORM is an appropriate security practice. Even if you use ORM (for example, in the PHP project), you may still receive SQL injection attacks. Inserting queries into ORM is much more difficult than usual, but linking an ORM query causes the same vulnerabilities as when connecting SQL queries. Therefore, do not connect the strings to be sent to the database. ORM also supports a prepared statement.

Be sure to inspect all ORM code to use and check how SQL execution is generated by that code. Make sure that a prepared statement is used instead of connecting the values inside and complies with the appropriate security measures.

Encoding problems

Use UTF-8 unless otherwise

Many of the new attack vectors are based on the detour of the encoding. Use UTF-8 for the database and application character sets unless you need to use another encoding.

Besides SQL, there are several executable and general injections in PHP.

Injection shell

The following few PHP functions

Run a string as a shell script or command. The input passed to these functions (especially the backtick (backtick) operator). In some cases, the injection of shell scripts may cause the application's configuration and configuration to be leaked or the whole server will be hooked. This is a very dangerous injection and considered the attacker's heaven.

Don't be sure to pass a contaminated input (i.e., an input that has been manipulated by a user) to the above function unless you have absolute certainty that it is not dangerous. Escape and no other measures are effective. There are many vectors to avoid each countermeasure. Don't believe the immature developer says.

Code injection

In addition to PHP, any interpreter language provides functions to receive strings and run them in the language. In PHP, this function is called eval(). The use of Eval is a very bad practice. Not only on security. If you have absolute certainty that there is no way other than Eval, use Eval with no tainted input. Eval is generally slow execution.

Do not use the preg replace() function with a non sanitary user input. The payload is evaluated with eval().

Reflection may also have a defect in code injection. For advanced topics, see the appropriate documentation for reflection.

Other injection

Other third party applications that run LDAP, XPath, and strings are vulnerable to injection. Keep in mind that the string must be a command and not a command, so you need to ensure that you need to pass it to the third party library.

There are two scenarios for XSS: We need to take appropriate measures.

No tag

In most cases, you do not need to include an unescaped HTML tag in the user input data at the time of output. For example, when dumping the value of a text box or outputting user data in a cell.

If you are using a standard PHP or a ` ` echo ` 'on a template, you can reduce the XSS by applying' htmlspecialchars' or the following functions (in fact, a more useful wrapper for the 'htmlspecialchars'). However, this is not recommended. The problem is that you have to remember to apply it every time, and once you forget it, you will find an XSS vulnerability. A default, unsafe methodology needs to be treated as dangerous.

Instead, we recommend using the template engine to apply the default HTML escape (see below). All HTML is passed via the template engine.

If you cannot switch to a safe template engine, use the following functions for all untrusted data.

Note that if you use a user input in a dangerous element (style, script, image SRC, a, etc), you can't reduce XSS in this scenario. However, it is not possible to do this. Also note that all of the output that is not intended to include HTML tags must be filtered from the next function and sent to the browser.

Untrusted Tags

Allow users to input HTML tags to be used in the output (rich blog comments, forum posts, blog posts), and if you are unreliable, you need to use a secure encode library. However, this is usually difficult and slow execution. This is because most applications have XSS vulnerabilities. OWASP esapi provides code groups to encode different parts of the data. There is also an htmlpurifier for OWASP antisammy and PHP. All of these settings require a lot of settings and learning to perform properly, but these are essential for developing good applications.

Template engine

There are several template engines that support programmers and designers in data output and defense against most XSS vulnerabilities. Although the main purpose of the template engine is not security, but the improvement of the design experience, most of the main template engines will force developers to automatically escape the variables on the output and specify if there is a variable that cannot be escaped. This causes the output of the variable to behave in the white list. There are multiple engines like this, but the preferred example is twig [1]. Other popular template engines include Smarty, haanga and rain TPL.

If you apply an escape manually, it is too easy to forget. Also, developers need to adopt a safe system by default if they focus on security.

Other tips

Although CSRF measures are theoretically simple, it is difficult to implement correctly. First there are some tips about CSRF.

OWASP PHP csrrguard is a code snippet that shows how to prevent CSPF. It is insufficient to copy and paste this. In the near future you will be able to copy and paste versions (hopeful observations). For the time being, we deal with the following hints.

PHP does not come with an immediately available authentication module. You must implement your own PHP framework or use the PHP framework. Unfortunately, most PHP frameworks are developed by an open source developer community, not a security expert, but far from perfect. Next, some useful and useful hints.

Session management

PHP's default session feature is considered safe. The phpsessionid generated is sufficiently random, but preservation is not always secure.

Hijack session

Binding a session to an IP address is an appropriate practice. This prevents most session hijack scenarios (but not all). However, there may be a user using an anonymization tool (TOR). These users have trouble with service.

To implement this, simply save the client's IP to the session at the first session of the session and force it to be the same again. The following code snippet returns the client's IP address.

Disable session ID

Disable the session every time a violation (e.g., two IP addresses is observed) (unlocked cookie, session save, trace deletion). Log events may be useful. Many applications also notify login users (e.g. Gmail).

Session ID

Roll session ID every time it raises. For example, if the user logs in, the session's importance changes, so you need to change the session ID.

Session ID exposure

Session IDs are considered highly confidential. Ensure that the application does not expose session IDs anywhere (especially bound to login users). Do not use URL as medium for session IDs.

If the session contains sensitive information, the session ID is always transferred via TLS. Otherwise, an ambush can perform session hijacking.

Fixed session

After the user's login (or after each request), disable session ID using session regenerator id().

Session expiration

After a certain idle time has elapsed, the session must be expired after a lapse of a certain activity time. An effective expiration process means disabling and deleting sessions and creating a new session when another request comes.

Close the logout button and untrace all of the sessions at logout.

Idle time timeout

If the current request expires x seconds after the last request, the session expires. This requires you to update the request time of the session data every time the request is made. The general configuration time is 30 minutes, but greatly depends on the conditions of the application.

This expiration is useful when logged in to a public accessible machine forgotten logged out. Session hijack is also valid.

General timeout

If the current session continues for a certain period of time, the session expires even if active. This makes it easy to grasp the situation. The period is different, but it usually takes about 1 to 1 week. To run this, you must store the session start time.


There are several knives to handle cookies in a PHP script.

Not serialized

Do not serialize the data stored in cookie. It is easily manipulated and may add variables to scope.

Proper deletion

To remove a cookie safely, use the following snippet.

In the first line, the cookie in the browser is reliably expelled. The second line is the standard way to delete cookies (false cannot be stored in cookie). In the third line, remove cookie from the script. Many guides recommend developers to expire using time() - 3600, which may not work if browser time is incorrect.

You can also use session.

Internet Explorer issues

As a trend, many versions of Internet Explorer have problems with cookies. The problem is usually solved by setting the expiration to 0.


Automatic me

Many web sites are vulnerable to automatic login functions. The correct approach is to generate a one-time token for the user and store it in cookie. This token must also exist in the application's data store to validate this token and assign it to the user. This token must be unrelated to the username or password, and is safe and long enough to be random.

This is recommended to prevent brute force attacks against an automatic login token. Also, ensure that the token has enough length. Otherwise, the attacker might have a brute force attack on the automatic login token, and eventually access the login user without credentials.

See PHP configuration chafe sheet.

Achim Achim at

Andrew van der stock

Luke plant

OWASP chop sheets project Homepage

Developer chute sheets (builder)

Assessment chute sheets (breaker)

Mobile chofes sheets

OPSEC chit sheets (defender)

Draft chate sheets