Secure PHP Settings

PHP is popular. It has many settings that affect the security of a system.

PHP settings are stored in the image from book  PHP.INI file. The current settings are returned by the phpinfo() function. In addition, a few PHP settings can be specified in the Apache configuration file whose default name is image from book  HTTPD.CONF . This is possible when PHP is used as a module of the Apache HTTP server. Certain settings can be specified in the . htaccess file. Note that settings in the admin section of the configuration file can be disabled or overridden in the . htaccess file.

Look more closely at each configuration directive that can affect system security.

Accessing Remote Files

The allow_url_fopen directive is a Boolean configuration directive. Turning it on allows you to access remote files available through HTTP or FTP using file functions just like local files:

 <?    $f=fopen("", "r");    while($r=fread($f, 1024)) echo $r;    fclose($r);    include("http//");    ?> 

When this directive is turned on, remote files can be included and executed. Therefore, turning it on is especially dangerous when a file name is contained in a variable that can be changed by a remote user . This is a vulnerability of the global PHP source code injection type. However, even if this directive is turned off, such a mistake in the include() function leads to a vulnerability of the local PHP source code injection type.

If an attacker is persistent enough, exploitation of the local vulnerability can allow him or her to achieve the same results as exploitation of the global vulnerability.

Both the local and the global types of the PHP source code injection vulnerability were described in Chapter 2 devoted to vulnerabilities in Web applications.

If the name of the file being opened (e.g., with the fopen() function) is specified with a variable that can be changed by a remote user, the attacker can obtain the contents of local files regardless of whether the directive is turned on or off. In some systems, however, it is necessary to open remote files. This directive shouldn't be turned off in such systems.

As you can see, turning off this directive doesn't save you from attacks made against vulnerabilities that can take place in file functions. In addition, it would destroy the functionality of some systems. Therefore, turning it off can be justified in only one case: You need to protect code that is likely to be vulnerable, but you don't have time or money to correct this code and eliminate vulnerabilities from it.

In any case, you should be aware that a skilful hacker can circumvent this protection.

At the same time, if your code meets all safety requirements, it doesn't matter whether the directive is turned on or off. In other words, the following note is true.


If the system security is thought out at the PHP script level, it is pointless to turn off this directive.

By default, this directive is turned on in PHP.

Displaying and Reporting Errors

The display_errors Boolean configuration directive tells the PHP interpreter whether it should display errors when executing code.

Many authors of books and articles recommend disabling this directive to increase the security level. Indeed, displaying errors isn't good programming style.

What's more, an error message indicates a situation that wasn't foreseen by the programmer. In other words, this is an undocumented response.

As I demonstrated earlier, undocumented responses of a system are used by attackers to gain control over it.

However, even when the directive for displaying errors is turned off, nothing will happen to undocumented responses. You just don't see an indication.

Therefore, turning off this directive will just relieve you of an indication of a vulnerability, not of the vulnerability itself. In Chapters 2 and 3 , I draw your attention to how an attacker can find and exploit vulnerabilities in a system when the error display is turned off.

In addition, turning off error messages can hamper tasks such as debugging the system, putting it into operation, adding new modules to it, and updating it. Again, a persistent attacker can exploit a vulnerability even when displaying errors is turned off.

A well-designed invulnerable system shouldn't enter undocumented states. Therefore, an outsider won't be able to change external conditions so that execution of a PHP script is terminated with an error.

So, turn off displaying error messages after you put your system into operation and make all necessary settings. Be aware that turning them off doesn't affect the system security; it would just be confusing, which is seldom effective.

Turn on the directive for displaying error messages during development and testing of the system and when adding new modules. This will help you debug undocumented responses of the system.

The error_reporting directive sets an error reporting level. For more details, refer to PHP documentation.

Magic Quotes

The magic_quotes_gpc directive is a Boolean configuration directive. When it is turned on, all quotation marks and apostrophes in HTTP GET, POST , and COOKIE parameters are screened with backslashes. That is, when the magic_quotes_runtime is turned on, quotation marks and apostrophes are screened in data returned by functions that retrieve information from external sources.

Thus, turning on these directives allows you to avoid processing received data when you're going to use them in SQL queries or other constructions that require screening of quotation marks, apostrophes, or both.

Some people say that turning on these directives eliminates the SQL injection vulnerability. However, in Chapter 3 devoted to this vulnerability, I demonstrated that an attacker sometimes can exploit this vulnerability without using quotation marks in parameters.

In many cases that display data in the browser, output data to a file, or use data in other functions that already take a backslash, turning on these directives will litter the output with backslashes. To avoid this, delete excessive backslashes before data output. You can use the stripslashes() function to do this.

When programming a system, you should keep in mind that quotation marks and apostrophes are screened automatically, and should delete the screening manually when necessary.

Taking into account that screening is not a panacea but just an inconvenience for a programmer and that it can lead to failure if the programmer is inexperienced, I would recommend that you don't use these directives. Rather, stick to simple safety rules when writing code. For example, convert data in SQL queries to the necessary form and screen dangerous characters manually, using appropriate functions.

Turning on magic quotes won't increase the system security level much but will hamper you as a programmer.

Global Variables

The register_globals Boolean configuration directive is responsible for registering GET, POST, COOKIE , and other HTTP parameters as global variables.

In earlier PHP versions, this directive was turned on by default; in later versions, it is turned off. However, in many systems it is turned on even in the latest PHP versions because they inherited old configuration files.

In Chapter 2 devoted to errors in Web applications, I demonstrated that with this directive turned on, an attacker sometimes can exploit errors related to the use of noninitialized variables. When the directive is turned off, the GET, POST, COOKIE , and other HTTP parameters can be accessed explicitly using the $_GET, $_POST, $_COOKIE, $_SERVER , and $_ENN arrays.


In the earlier PHP versions, the $HTTP_GET_VARS, $HTTP__POST_VARS, $HTTP_COOKIE_VARS, $HTTP_SERVER_VARS, $HTTP_ENV_VARS arrays were used.

Even when the directive is turned on, I recommend that you use these global arrays explicitly, when accessing external parameters, for compatibility. In addition, I recommend that you explicitly declare local and global variables to avoid using them without initialization.

With an appropriate approach to Web programming, it doesn't matter whether the directive is turned on or off. You'll obtain correct and reliable code regardless of the state of this directive.

If code is written with the presumption that the directive is turned on that is, the GET, POST , and COOKIE parameters are accessed as global variables the code won't be portable to systems with this directive turned off. Therefore, you should write code with the presumption that the directive is turned off and access external data explicitly by using appropriate arrays and declaring all variables.

In most cases, it is recommended that you turn off this directive because it is pointless to use it when a correct approach to Web programming is used. Leave it turned on only when there are system scripts that require it. Make sure the scripts are safe.

The variables_order directive sets the order of parsing the GET, POST, COOKIE , and other HTTP parameters and specifies, which parameters should be converted to global variables.


In the earlier 3.x PHP versions, the gpc_order directive is used rather than variables_order.

Exposing PHP

The expose_php directive is a Boolean configuration directive. When it is turned on, information that a document was generated using the PHP interpreter is exposed in the HTTP header of the server's response. The version of the interpreter is also disclosed. When the directive is turned on, PHP exposes this information; otherwise (expose_php = off), no additional data are sent to the browser.

Be aware that disabling this directive just creates confusion. Don't base system security on the hope that an attacker doesn't know how documents are generated (with PHP or Perl) or what PHP version is installed in the system.

An attacker can assume that your documents are generated with a PHP interpreter and try to find vulnerabilities in your PHP scripts. In addition, he or she can know from other sources that the documents are generated with a PHP interpreter.

For example, if his or her browser displays a PHP error message or such a message appears in a search engine's cache, the attacker will have no doubt that you use PHP.

Extensions of document files can allow the attacker to detect a PHP interpreter.

However, I demonstrated earlier how you can associate any file extension to the PHP interpreter on the server. Consider an example:

 RemoveHandler .htm .html .jpg .gif .png .bmp .jpeg    AddType application/x-httpd-php .htm .html .gif .png .bmp .jpeg .jpg 

In this example, the Apache HTTP server is configured so that documents with the HTM, HTML, GIF, PNG, BMP, JPEG, and JPG extensions are processed by the PHP interpreter.

In addition, the attacker can send an HTTP request to any PHP script (e.g., http://localhost/6/1.php) regardless of its extension. Suppose that the following lines are contained in the requests as HTTP GET parameters:

  • http://localhost/6/1.php?=PHPE9568F34-D428-11d2-A769-00AA001ACF42

  • http://localhost/6/1.php?=PHPE9568F35-D428-11d2-A769-00AA001ACF42

  • http://localhost/6/1.php?=PHPE9568F36-D428-11d2-A769-00AA001ACF42

  • http://localhost/6/1.php?=PHPB8B5F2A0-3C92-11d3-A3A9-4C7B08C10000

The results of these requests will be surprising regardless of the PHP settings and the logic of the PHP scripts. The first request displays the PHP logo. The second request displays the Zend logo. Depending on the PHP version, the third request displays a picture of a dog or of a man chewing a pencil.

The fourth request is the most interesting. It displays the names of PHP developers. In addition, the following data might be displayed.


PHP 4.3 Quality Assurance Team

Ilia Alshanetsky, Stefan Esser, Moriyoshi Koizumi, Sebastian Nohn, Derick Rethans, Melvyn Sopacua, Jani Taskinen

Therefore, an analysis of server responses to these (and a few other) requests allows the attacker to find the version of the PHP interpreter used on the server.

Other Configuration Directives

The include_path directive sets paths to include files.

In some cases, when this directive is set incorrectly and the local PHP source code injection vulnerability takes place, the attacker can include and execute any local file even if the .. / sequence is filtered. For example, this is possible when the include_path directive specifies the root directory on the server (and the mentioned vulnerability takes place):


The post_max_size directive defines the maximum size of an HTTP POST request. If you're going to send large amounts of data in POST requests, increase the value of this directive.

When you process file loading, the maximum size of an HTTP POST request should be larger than the maximum allowable file size because files are sent using the HTTP POST method.

The upload_max_filesize directive puts additional limits on the size of loaded files. Unlike with the hidden form field MAX_FILE_SIZE , the client cannot bypass this directive.

The max_execution_time directive sets the maximum execution time for PHP scripts. When the value of this directive is large, the malicious user can launch a DOS attack on the server scripts that run long enough.

However, you shouldn't make this value too small. Otherwise, large scripts won't be able to terminate normally. Rather than minimizing the value of this directive, optimize your scripts so that they consume minimum computer resources.

Note that the execution time of a script doesn't include the time required to make database queries or the time taken up by functions such as sleep() or system() .

The set_time_limit() function sets the maximum execution time for a script and resets the counter when the script runs.

The memory_limit directive sets the maximum size of the memory that can be taken up by a script. This parameter prevents a malicious or erroneous script from taking up all available memory and causing a DoS failure.

The Safe Mode

The safe_mode configuration directive turns on the safe PHP mode.

In the safe mode, a few additional configuration directives that strongly limit the server functionality are used. The following paragraphs describe limitations put on a script when the PHP interpreter is in the safe mode.

In the safe mode, PHP checks whether the owner of script is the same as the owner of a file accessed by the script. For example, let the image from book  TEST.PHP script belong to the test user, and let the image from book  TEST.TXT file belong to the test2 user. The access rights are the following:

 -rw-rw-r--     1 test    test         11 Jan  1 00:00 test.php    -rw-rw-r--     1 test2   test         11 Jan  1 00:00 test.txt 

Let the image from book  TEST.PHP script have the following code:

 <?     $f=fopen("text.txt", "r");     while($r=fread($f, 1024)) echo $r;     fclose($f);    ?> 

When this script starts in these conditions, the following message will appear.


 Warning!: SAFE MODE Restriction in effect. The script whose uid is 1001 is not allowed to access test.txt owned by uid 1002 in test.php on line 2 

Note that the message appears even though the test2 user and the user who started the Apache HTTP server have the rights for reading the image from book  TEST.TXT file.

In many cases, this check doesn't affect the security of a system. Suppose an attacker exploits a vulnerability and can start any PHP code on a server. In addition, suppose the attacker exploits the PHP source code injection vulnerability in a script, say, TEST1.PHP. This script can belong to a user other than the user who started the HTTP server. What's more, the other files in the system are likely to have the same owner.

By exploiting this vulnerability, the attacker can access the other files as long as the access rights of the user who started the HTTP server allow the attacker to do this. Because the vulnerable script belongs to the same user as the other scripts in the system, the check will return positive results.

If the attacker uses this vulnerability to put a malicious PHP script into a folder available for writing, this file will belong to the user who started the HTTP server. Thus, the attacker will be able to work with files belonging to that user.

So, this check doesn't guarantee security because attacks can exploit the mentioned vulnerability. At the same time, this check significantly hampers the development of scripts and disables certain system features.

The open_basedir directive can be used instead of safe_mode . If the value of the open_basedir directive isn't empty, no files outside the specified directory can be processed. Everything I said earlier about the check for file owners is true when it comes to this directive.

The use of this directive won't protect you from the attacker's access to files located in the same directory or in a directory that contains a vulnerable file. Thus, the attacker can obtain access to reading and editing system files that can contain private data.

The doc_root directive is similar to open_basedir . If the PHP interpreter is in the safe mode, no files outside the specified directory can be processed.

In addition, the following configuration directives can be used in the safe mode:

  • safe_mode_gid When this directive is turned on, the PHP interpreter checks whether the group that owns the script is the same as the group that owns the file being processed. Turning on this directive weakens the safe mode to some extent.

  • safe_mode_exec_dir The directive specifies a list of paths so that only files with these paths can be executed. The details are given later.

  • safe_mode_include_dir If included files belong to the directory specified in this directive, no checks are done for owners (or groups of owners) of the included files. The directory specified in this directive should be specified in the include_path directive, or you should specify the absolute path to the file.

  • safe_mode_allowed_env_vars The directive specifies a list of environment variables that can be changed with a script. By default, the variables whose names have a PHP _prefix can be accessed. You shouldn't hope that preventing the attacker from accessing the environment variables will affect his or her destructive abilities .

  • safe_mode_protected_env_vars The directive contains a list of environment variables that cannot be changed with the putenv() function. This directive has a higher priority than the safe_mode_allowed_env_vars directive. Therefore, if the same variable is contained in both directives, it will be inaccessible.

  • disable_functions The directive lists PHP functions that cannot be used in scripts. This directive works regardless of the safe mode.

  • disable_classes The directive prohibits the use of particular classes. This directive works regardless of the safe mode. This configuration directive was introduced in PHP 4.3.2.

The safe mode restricts the use of certain functions.

Before opening a file (for reading or writing), all file functions check whether the owner (or the group of owners) of the script is the same as the owner (or the group of owners) of the file being processed.

I should mention that earlier PHP versions suffered from vulnerabilities that allowed an attacker to circumvent this restriction:

Variant 1. In earlier PHP versions, it was possible to use the include() function to include text files and display them to a browser even when the safe mode prohibited this. The attacker can obtain the contents of any file in vulnerable PHP versions when the target file is available for reading to the user who started the HTTP server and the safe_mode_include_dir isn't set.

Viewing a file with safe mode on

 <?  Include("/etc/passwd"); ?> 

Variant 2. The attacker can try to access a database. He or she can create a malicious script that sends a query to the database and returns the contents of the target file.

Viewing a file using MySQL

 <? mysql_connect("localhost", "root", ""); $sq="select load_file('/etc/passwd' as file)"; $q=mysql_query($sq); if($r=mysql_fetch_object($q)) {  echo "<pre>".htmlspecialchars($r->file)."</pre>"; } else { echo "ERROR. The file cannot be loaded!"; } ?> 

Variant 3. Although the PHP interpreter is good, its earlier versions contain a few bugs that allow a malicious user to circumvent the safe mode. The attacker can exploit these bugs to obtain higher privileges in the system and access any file.

The putenv() function checks the user's rights for changing environment variables listed in the safe_mode_allowed_env_vars and safe mode protected_env_vars directives.

The move_uploaded_file() function checks whether the script and the file have the same owner (or group of owners).

The chdir() function allows the user to change the directory only if the directory and the file have the same owner (or group of owners).

The dl() function is unavailable in the safe mode. The shell_exec() function and the "back quotes" operator are also unavailable in the safe mode.

The exec () , system() , passthru () , and popen() functions can be used for executing files within the directory set with the safe_mode_exec_dir directive.

The use of the .. sequence in file paths is prohibited.

The last fact makes it impossible for an attacker to use the PHP shell. However, an incorrect configuration (e.g., where the root directory of the server is specified in the safe_mode_exec_dir directive) will reduce to zero all protection set with the safe mode. A malicious authenticated user will be able to execute any file that can manipulate other files regardless of who their owners are.

If apache_request_headers() is used in the safe mode, authorization headers in an HTTP request aren't returned.

The header() function adds the current user ID (UID) to the WWW-Authenticate header.

The PHP_RUTH_USER , PHP_AUTH_PW , and AUTH_TYPE elements of the $_SERVER array are unavailable in the safe mode. However, in PHP 4.2.1 and later, the $_SERVER [REMOTE_USER] element can be used to identify an authorized user.

The set_time_limit() function is unavailable in the safe mode. In the mail() function, the fifth parameter is unavailable in the safe mode.

To summarize, the safe mode protects scripts and data belonging to users from scripts belonging to other users, and it protects the system from malicious scripts.

At the same time, the safe mode decreases the system's functionality and is inconvenient to users and programmers.

In other words, the safe mode is a tool for protecting users from other users in a hosting company. It doesn't save the system from external dangers.

Vulnerabilities of the SQL injection type can be exploited with methods described earlier in this book. The safe mode doesn't affect the attacker's ability to exploit these vulnerabilities.

Vulnerabilities related to obtaining the contents of any file are restricted with the requirement that the file should belong to the same user. However, if the attacker analyzes system files, this requirement is met. In other words, the vulnerability can be used to investigate the system and, sometimes, to deface pages on the site.

Vulnerabilities of the PHP source code injection type can be used as described earlier. The only limitation is that the attacker will fail to flush PHP shell to a remote server because the functionality of the system() function is limited in the safe mode.

As you can see, the safe mode leaves many ways for destructive actions, and it involves inconvenience for programmers.


Enabling the safe PHP mode doesn't mean complete protection for the system. At the same time, proper filtration and the use of other methods described in this book allow you to increase the reliability and security of the system.

Hacker Web Exploition Uncovered
Hacker Web Exploition Uncovered
ISBN: 1931769494
Year: 2005
Pages: 77 © 2008-2017.
If you may any questions please contact us: