Security and Hardening Tips for PHP

  1. Disable sensetive functions in PHP


    Edit the php.ini file :

    sudo vi /etc/php5/apache2/php.ini

    Add or edit the following lines an save :

    disable_functions = exec,system,shell_exec,passthru,etc ......
    register_globals = Off
    expose_php = Off
    display_errors = Off
    track_errors = Off
    html_errors = Off
    magic_quotes_gpc = Off
    

    Restart Apache server. Open a Terminal and enter the following :

    sudo /etc/init.d/apache2 restart

  2. Disable allow_url_fopen ( enabled by default )


    This directive allows PHP’s file functions ( file_get_contents, include and require statements ) to retrieve data from remote locations, like FTP or HTTP.

    If an attacker can manipulate the arguments to those functions, they can use a URL under their control as the argument and run their own remote scripts. The vulnerability is called Remote file inclusion or RFI.

    ; Disable allow_url_fopen in php.ini for security reasons
    allow_url_fopen = Off

    The setting can also be applied in apache’s httpd.conf :

    # Disable allow_url_fopen for security reasons
    php_admin_flag allow_url_fopen Off

    It prevents URLs from being used in PHP. A command like include (“http://www.example.com/evil_script.php”) will not be allowed to execute. Only files that reside within your site can be included: include(“/var/www/html/config.inc.php”).

    NOTE: A large number of code injection vulnerabilities reported in PHP web applications are caused by enabling allow_url_fopen and bad input filtering. You should disable this directive for security reasons.

  3. Disable Display Errors


    The display_errors directive determines whether error messages should be sent to the browser. These messages frequently contain sensitive information about your web application environment and should always be disabled.

    ; Disable display_errors in php.ini for security reasons
    display_errors = Off
    log_errors = On

    The setting can also be disabled in apache’s httpd.conf or .htaccess file:

    # Disable display_errors for security reasons
    php_flag display_errors Off
    php_flag log_errors On

    NOTE: display_errors should be disabled and all error messages should be passed to system log files using the log_errors directive.

  4. Disable magic_quotes


    magic_quotes_gpc provides some rudimentary protection against SQL injection and is a generic solution that doesn’t include all the characters that require escaping. It effectively executes addslashes() on all information received over COOKIE, GET and POST. Because it’s inconsistent and ineffective, it’s recommended to disable magic_quotes_gpc. Rely on input filtering done by your scripts.

    ; Disable Magic Quotes in php.ini for security reasons
    magic_quotes_gpc = Off
    
    # The setting can also be applied in apache's httpd.conf or .htaccess file:
    php_flag magic_quotes_gpc Off

    NOTE: If the magic_quotes_sybase directive is also On it will completely override magic_quotes_gpc. Having both directives enabled means only single quotes are escaped as ”. Double quotes, backslashes and NUL’s will remain untouched and unescaped.

  5. Disable register_globals


    A number of older scripts assume that the data sent by a form will automatically have a PHP variable of the same name.

    If your form has an input field with a name of “somename”, older PHP scripts assume that the PHP will automatically create a variable called $somename that contains the value set in that field.

    ; Disable register globals in php.ini for security reasons
    register_globals = Off

    The setting can also be applied in apache’s httpd.conf or .htaccess file:

    # Disable register globals for security reasons
    php_flag register_globals Off

    NOTE: Register Globals should always be disabled.

  6. Protect PHP Sessions


    Protect your sessions from being hijacked or shared in links people post online or send to friends by enabling cookie httponly. It will also prevent Javascript from reading your cookies.

    session.cookie_httponly = 1
    
    Also add a referer check, like:
    
    session.referer_check = yourwebsite.com
    

    You might want to change your default session save path to somewhere hackers won’t find as easily. E.g:

    session.save_path = /var/lib/php

  7. Disable use_trans_sid


    When use_trans_sid is enabled, PHP will add a unique PHPSESSID query pair to URIs within your site if cookies are not available and session.use_trans_sid is set. This makes it far easier for a malicious party to obtain an active session ID and hijack the session. It’s recommended to disable use_trans_sid in your PHP environment.

    ; Disable use_trans_sid for security reasons
    session.use_trans_sid = Off
    

    The setting can also be disabled in apache’s httpd.conf or .htaccess file:

    # Disable use_trans_sid for security reasons
    php_flag session.use_trans_sid Off

  8. Make use of correct php.ini file


    Each PHP installation has two set of php.ini files namely “php.ini-production” and “php.ini-development”.
    Safe to say that there is quite number of opinions on what should be enabled and what should be disabled. Most of the disagreement arise from the conflict of interest between those using PHP in production and those using it for development. Developers want display_errors on, they want to see E_NOTICE and E_STRICT errors, while those who use PHP in production want to rather log errors to a log file or syslog, and then nothing but the most critical of errors.

    Main difference between the values of these two versions of files are

    	short_open_tag
    	disable_functions 	
    	memory_limit
    	session.gc_probability 
    	display_startup_errors 
    	track_errors
    	error_reporting
    

  9. Restrict File Uploads (Application Specific


    If you’re not utilizing file upload functionality in any of your PHP scripts then it’s a good idea to turn it off. Attackers will attempt to (mis)use file uploads to quickly inject malicious scripts into your web applications. By disabling file uploads altogether this makes moving scripts onto your web server more difficult. To disable file uploads change the file_uploads directive in your php.ini to read:

    file_uploads = Off

    Even if you do allow file uploads you should change the default temporary directory used for file uploads. This can be done by changing the upload_tmp_dir directive. You may also want to restrict the size of files that can be uploaded. This is usually more of a system administration alteration than a security fix, but it can be useful. Use the upload_max_filesize directive for this purpose. To restrict upload directories and file sizes change your php.ini so that it reads:

    upload_tmp_dir = /var/php_tmp
    upload_max_filezize = 2M
    

  10. Analyse PHP Setting using “PhpSecInfo”

    PhpSecInfo provides an equivalent to the phpinfo() function that reports security information about the PHP environment, and offers suggestions for improvement. It is not a replacement for secure development techniques, and does not do any kind of code or app auditing, but can be a useful tool in a multilayered security approach.

    Ref: http://phpsec.org/projects/phpsecinfo/