25 Years of Programming
An open source source for C, C++, OWL, BASIC, MDB, XLS, DOT, and more...
Home   Projects   Sitemap   Search   Blog   Forum+Chat   About Us   Privacy   Terms of Use   Feedback   FAQ   Images   Services   Ads   Donate

PHP Security:

cPanel:

Botnets:

Website traffic:

Monetize website:

Security precautions before you start using PHP on your Apache server, step by step

Introduction - what is PHP?

PHP is a server side scripting language. You can embed PHP code in your web pages along with HTML. When your server receives a request for a page, it first gives the page to the PHP handler program. The PHP handler outputs HTML code as-is, but when it encounters PHP commands, it executes them. Any HTML generated by the PHP commands is also output. The end result is a web page with content that has been customized on the server before being sent to whoever requested it.

PHP is fairly easy to learn and fun to use, so many people start using it without giving much thought to security. Too often, the result is a hacked website. PHP has commands that a hacker can use to take complete control of a website. You don't have to be a master of security to prevent them from doing it, but you do have to avoid leaving the door open for them.

This article is a simple guide to the most basic steps to perform before starting to use PHP.

It assumes your site is on an Apache server with .htaccess enabled.

There are two files where PHP configuration commands can go: php.ini or .htaccess. Php.ini is better, and you should be able to use that method in Section 1a) below if:

  • You are on shared hosting at a webhost that uses suPHP, or
  • You are on a dedicated hosting plan (your own rented server), or
  • You host your own website on your own server.

If you are not able to use php.ini, configuration commands can go in .htaccess. See Section 1b) below.

1a) Configure PHP settings with a php.ini file

Php.ini specifies the configuration settings PHP will use when it is running on your website. The following settings affect security.

In your public_html (the same folder where your site's main home page is), create a text file called php.ini that contains these lines. The lines require a minimum amount of customization, in red and described below:

allow_url_fopen = Off
display_errors = Off
display_startup_errors = Off
log_errors = On
error_reporting = E_ALL
error_log = /home/yourUserID/public_html/phperr.txt
expose_php = Off
magic_quotes_gpc = On
magic_quotes_sybase = Off
register_globals = Off

Explanations:

These explanations are brief. This page of the PHP Manual has links to more.

allow_url_fopen = Off

allow_url_fopen is especially important. It prevents URLs from being used in include() statements and in some other places, so that a program statement such as include("http://anything...") will not be allowed to run. Only files that reside within your website can be included. You won't be able to include a file from a different server, but neither will a hacker. When someone else does it maliciously, it's called a Remote File Inclusion (RFI) attack. 99% of the attacks on this site, thousands of them, are RFI's, and this security setting dooms them all to fail.

display_errors = Off
display_startup_errors = Off
log_errors = On
error_reporting = E_ALL

These specify that all errors and warnings will be logged to your error log text file. NO errors or warnings will be displayed on any web page that is sent out from your server. Errors displayed on web pages give hackers information that helps them learn how to better attack your server. Sometimes hackers try to provoke errors on purpose to obtain this information. Check your error log frequently. 

error_log = /home/yourUserID/public_html/phperr.txt

This defines the path and file to which your PHP errors and warnings are logged. Change yourUserID to the cPanel or other UserID assigned to you by your webhost. The filename can be anything you want. The path starting with /home seems to be a common one in Linux, but it might vary depending on your web host. If the above doesn't work, ask them what it should be. public_html is only shown above as an example of where it fits in the path. You don't have to put your error log in or below public_html. See below.

I recommend using a text file for error logging (as shown above), and not using the "system log" option that you might see mentioned. The Apache system log seems to be flushed at very short intervals, so you might not see all your errors.

Your error log file should be in an area of your webspace that is not publicly accessible. Protect it by one of these methods:

  1. Put it in a folder above /public_html.
     
  2. Protect it with an .htaccess file that prohibits web access, like this:

    In cPanel > File Manager, create the folder.
    Inside the folder, create a file called .htaccess (with the leading period).
    Put this text in the file:

    order allow,deny
    deny from all

    Save the file.
    Test it by trying to go to http://yoursite.com/foldername/
    You should get a 403 Forbidden error page.
     
  3. Apply password protection to it. You can do this in cPanel.

With a) and b), you can only view the file with cPanel > File Manager or FTP, not by browser.

expose_php = Off

Not particularly important, but it doesn't hurt.

magic_quotes_gpc = On

The PHP manual recommends setting this to Off, and dealing with quotes in a secure manner on your own, but we're assuming you don't know how to do that yet, and that you also don't actually have any need yet for the situations it addresses, so for now the best setting is On.

magic_quotes_sybase = Off

Another special setting of "magic quotes". This should be Off.

register_globals = Off

register_globals is especially important. You've probably seen URLs that look like this: http://site.com/index.php?something=somevalue. When register_globals is On, the variable called something is passed into your script with its value set to somevalue. With register_globals Off, variables passed in like this are not automatically dumped into your script's variable list. This makes it harder for hackers to inject their own code.

safe_mode = Off

This setting is not in the "recommended php.ini" above. I only mention it because you might run across it and wonder what it is and how it should be set. It restricts the permissions with which PHP scripts run. However, some very popular third party scripts, which you are likely to want to use eventually, will not run properly when it is set to On. If your web host uses suPHP, safe_mode is even less necessary. Lastly, starting with PHP 6, safe_mode has been eliminated, anyway, so it is best left out of your php.ini file, or, if present, set to Off.

What if the above php.ini settings don't work?

If you ever write code that won't run properly with the above settings, that is a sign that you're not a beginner anymore, and you need to devote some serious study to PHP security before you go any further. The Security section of the PHP Manual is one reference that should be studied, but it isn't easy reading and might not be the best introduction. 

1b) Alternative: configure PHP in .htaccess

If you are on shared hosting at a webhost that does not use suPHP, you can still configure PHP by putting your configuration commands in .htaccess instead of php.ini. Unfortunately, not all php.ini commands have .htaccess equivalents, but some of them do.

Put the following lines in a part of your public_html/.htaccess file that is not delimited by HTML-style tags such as the <Files></Files> tags in the example in Section 2 below. The following lines have the same effects as their php.ini counterparts described in section 1a) above:

php_flag display_errors Off
php_flag display_startup_errors Off
php_flag log_errors On
php_flag magic_quotes_sybase Off
php_flag magic_quotes_gpc On
php_flag register_globals Off
php_value error_log /home/yourUserID/public_html/phperr.txt
php_value error_reporting E_ALL

The most important is the register_globals line.

Very unfortunately, allow_url_fopen = Off has no .htaccess counterpart. Because you cannot stop PHP from reading a file from a remote server, you need to make sure requests that try to open remote files are blocked before they can even be processed by PHP. A previous article has instructions how to use .htaccess to block requests that might be Remote File Inclusion attacks.

The following two also cannot be set in .htaccess, but they are unimportant:
expose_php = Off
safe_mode = Off

Viewing your PHP settings

Your server can provide you a complete report of all your PHP settings.

  1. Create a text file with a .php extension, containing just this line:

    <?php phpinfo(); ?>
     
  2. Upload it to your server into (preferably) a password protected folder.
  3. Open your browser and type the path into the address bar:
    http://yoursite.com/whatever/filename.php.
  4. Enter your username and password to enter the protected folder and view the result page.
  5. Save or print the result page to your local computer for reference.
  6. Delete the .php file from your server. It is not a good idea to leave this file lying around where it might be executable. The information it generates is very useful to a hacker.

2) Modify your .htaccess file

  1. Required: In your public_html/.htaccess file, add the following lines if they are not already there. Reference information for these lines is in the Apache manual section for mod_access:

# This denies all web access to your php.ini file.
<Files php.ini>
order allow,deny
deny from all
</Files>

  1. Required: If your web host uses suPHP, you will need to enter a suPHP_ConfigPath line. It will look something like this, but if this doesn't work, ask your web host what the line should be. Put this in a part of the file that is not delimited by HTML-style tags (such as the <Files></Files> tags in the paragraph above):

    suPHP_ConfigPath /home/yourUserID/public_html
     
  2. Optional: If you are adding PHP code to your existing .html files and don't want to rename them all to .php, you can instruct the server to send all .html files through the PHP processor as though they had .php extensions. To do that, add one of these lines into .htaccess, in a part of the file that is not delimited by tags. If one doesn't work, try another; experiment.

    If you are using suPHP:
    AddHandler x-httpd-php .htm .html

    If you are not using suPHP:
    AddType application/x-httpd-php .htm .html

    Apache 2 without suPHP:
    AddHandler application/x-httpd-php .htm .html

3) One more php.ini setting, advanced...

The settings list in Section 1a) was supposed to be as simple as possible, usable by anyone, with a minimum of effort required, but there is one more php.ini setting that's worth using if you can. Here is an example of its use, with a list of some of the functions that could be disabled for increased security:

disable_functions = exec,shell_exec,passthru,system,eval,show_source,proc_open, popen,parse_ini_file,dl,(comma-separated list of function names)

This tells PHP not to allow the use of the functions listed. Some powerful functions are used extensively and effectively by hack scripts, so if you block these functions, you can block the scripts from doing damage.

However, some of these functions are used by popular third party PHP scripts such as forums, blogs, galleries, and shopping carts, so the reason I call this an "advanced" setting is that before using this line you must search all the PHP code in your website to make sure you don't disable any functions that your site requires. Nevertheless, disabling functions you don't use is worthwhile if you don't mind doing the research.

disable_functions is for php.ini only. It has no .htaccess equivalent.

4) Memorize these best coding practices

Beginner Rules:

  • Never use the PHP eval() function.
  • Never use PHP to interact with a database.
  • Never use the $_GET, $_POST, $_COOKIE, $_REQUEST, or $_FILES variables. These bring data into your script from the outside world. The data has the potential of being malicious.

Advanced Rule:

When the time comes that you need to break one of the Beginner Rules, first do a web search on: PHP security and spend several days studying the results and practicing proper coding techniques for the methods and functions you plan to use. 

5) Things to do

If necessary, email your web host. Ask these questions, and then modify your php.ini or .htaccess file as needed:

  1. I want to create an error log for PHP. Are these paths ok?

    php.ini  : error_log = /home/yourUserID/public_html/phperr.txt
    .htaccess: php_value error_log /home/yourUserID/public_html/phperr.txt

     
  2. Does my server use suPHP? If so, is this the correct line for .htaccess?

    suPHP_ConfigPath /home/yourUserID/public_html

6) You're ready to start. Good luck and have fun.

Additional security precautions for protecting your website are at
Step By Step Repair After A Website Hack, and How To Prevent It.


If you have questions, feel free to ask in the discussion forum

 

 

Valid HTML 4.01 Transitional Valid CSS
View content labeling at ICRA.
Copyright ©2008 Steven Whitney. Last modified 05/09/2008.