PHP Security – Configuring the php.ini file properly

Posted by Serge Truth on October 31, 2013 at 9:27 AM
An important step in hardening the PHP environment is configuring the php.ini file properly and disabling functions that may be useful to an attacker but not necessary to the application. However, make sure that PHP is patched at least to version 5.4.0 because major security-relevant changes have been made beyond that.

Generally speaking, some PHP functions have no legitimate use and often result in vulnerabilities - most notably, the ability to "include" remote files as code. This functionality is singularly responsible for a whole class of dangerous and scalable attacks known as RFI (Remote File Inclusion). To disable including remote files in code, add the following lines to php.ini: "allow_url_include 0" and "allow_url_fopen 0".

Functions that allow PHP to execute operating system commands should be disabled if they are not needed by the application. Doing so helps prevent command injection vulnerabilities. If all functions that can execute OS commands are disabled, command injection exploits will not work; however the application code itself might still be technically vulnerable (later in my blog, I’ll describe how to prevent command injection vulnerabilities in code properly, but for now, the point I want to make is that disabling command execution functions is an important defense in depth measure.) Disabling OS command execution also significantly reduces the capabilities that a successful compromise affords an attacker- executing privilege escalation exploits becomes nearly impossible. The following are functions that may be used to execute OS commands: "exec, passthru, shell_exec, system, proc_open, popen, curl_exec, curl_multi_exec, pcntl_exec, dl". If the application needs to execute OS commands, it should use "pcntl_exec", because it provides better abstraction of parameters than the others.

I highly recommend disabling the "eval" function. "Eval" is dangerous and should be avoided as much as possible. Virtually every PHP botnet relies extensively on the "eval" function to inflict damage. Unfortunately, many applications use it even when it’s not necessary. Most applications can and should be written without using the "eval" function at all, and then it should be disabled. If possible, disable the "eval" function in php.ini. If doing so breaks the application, rewrite the portions of the application that use "eval" and then disable "eval" in php.ini. It is necessary to install the Suhosin hardened PHP patch to be able to disable "eval" in the php.ini file because technically "eval" is a language construct and not a function. Once the Suhosin hardened PHP patch is installed, "eval" can be disabled by using "suhosin.executor.disable_eval" and "suhosin.executor.disable_emodifier" directives.

Functions that can be used to use the application server as a DoS attack platform should be disabled. A server usually has a lot more bandwidth available than a personal PC. Therefore, attackers favor servers to perform flood-type DoS attacks. Disabling the "fsockopen" network function in php.ini helps prevent attackers from using the application server as a platform to stage DoS attacks.

Functions that send e-mail should be disabled, unless they are needed by the application. Compromised servers are often used to send out spam. Disabling PHP functions that send e-mail helps prevent attackers from being able to send spam using the application server. Again, it is important to also disable the PHP functions that can execute OS commands because an attacker might upload their own spam software to the server if these functions are available. However, disabling PHP functions that send e-mail in php.ini will also prevent the application from being able to send e-mail. Care should be taken in situations where the application relies on this functionality (i.e. to sends e-mails to help users reset their passwords.) The "mail" function should be disabled to prevent PHP applications from sending e-mail.

Functions that can be used to obfuscate malicious PHP code should be disabled, unless needed by the application. The most prominent of these functions are "gzdeflate, gzuncompress, gzinflate, zlib_decode, base64_decode". Technically, all the other functions for extracting compressed archives and working with different encodings might also be used to obfuscate PHP code. It should be noted that PHP code obfuscation techniques usually rely on the "eval" function and disabling the "eval" function will break most obfuscated malicious PHP code.

The scope of files accessible by PHP should be limited using the"open_basedir" directive. The most logical setting for the"open_basedir" directive is the web application root folder (not the filesystem root!).

Information disclosure via PHP error messages and banners should be disabled using the following directives: "display_errorsstderr" and "expose_php 0". These error messages provide great assistance to an attacker, especially during attempted SQL injection attacks.

Disabling unnecessary PHP functions helps reduce attack surface and the potential for abuse in the event of a successful compromise. Reducing the abilities of the application server reduces the value of compromising it to the attacker. The real application security controls are accomplished in the application's code, but hardening the server by disabling unnecessary PHP functions is a valuable defense in depth measure.

Topics: developer guidance, application security

Serge Truth

Written by Serge Truth

Serge is a Content Lead here at Security Innovation. He is an IT and Information Security professional, certified by the Committee on National Security Systems Instruction.