PHP is one of the most popular languages for web development today. As a result, hackers are always looking for ways to exploit PHP scripts to gain unauthorized access or cause damage to systems. Securing your PHP code is essential in any web application that you develop.
When looking at securing your PHP application there are two main categories of methods for securing your code. The first category involves settings in PHP itself, via php.ini, that affect the overall security of your application. The second category deals with coding best practices and writing secure code to prevent exploits.
Securing PHP via php.ini
There are a number of setting within PHP itself that can affect the security of your applications. These settings can be controlled through the php.ini file. By controlling the default behavior of PHP itself, you reduce the potential damage that coding errors might cause.
Kill Register Globals
Before version 4.2.0, PHP used global variables to provide access to input variables from GET and POST requests. This feature was done away with because it provided a security loophole. Attackers could use it to manipulate variables under a variety of scenarios. To provide backward compatibility, however, PHP provides the register_globals setting in php.ini. When this is on, PHP will provide the earlier behavior and register global variables for the input values. To secure your PHP, installation you should always turn this off. Avoid scripts that require register_globals as it is usually a sign of a potentially insecure script or one that has not been maintained or updated recently.
Controlling File Access
PHP scripts can use the fopen function to read and write files on the server filesystem. This is, of course, a necessary and desirable capability. However, it can also be a security risk. A coding error in a PHP script could allow a malicious user to read system files or overwrite files. Fortunately, there are a number of settings in PHP that allow you to control which files PHP can access.
One option you can use in php.ini is open_basedir. This option takes a sub-directory as its value such as /home/user/html/. It restricts PHP’s I/O to that sub-directory which prevents PHP from reading or writing files outside of that sub-directory.
You can also use safe_mode in php.ini to control access to files. In safe mode, PHP is only able to open files that are owned by the same user as your web server. It also prevents PHP from executing binaries. If you need to allow PHP to access files that are owned by different owners you can use safe_mode_gid. This limits PHP’s access to only files that are owned by the group that your web server runs under.
While security by obscurity is not sufficient to protect your application, it does make it harder for potential hackers to exploit your site if they do not know what technologies are behind it. PHP exposes itself in a number of ways including inside the Apache headers and in the Apache footer signature. You can turn off this behavior with expose_php = off in php.ini.
Another way that PHP exposes its presence is through the display of errors. These errors often include path information and other settings that a hacker will find invaluable. These error messages are invaluable during development for testing and debugging but they should be turned off on production sites. You can turn them off by setting: display_errors = Off in php.ini. A useful feature is to have the error messages logged to a log file instead which you can do by setting: log_errors = On in php.ini.
Finally, you can configure use Apache to rewrite your URLs so as to hide the .php ending. Many PHP frameworks such as CakePHP also hide the file extension through their URL routing. This helps hide the presence of PHP. It also makes your site more flexible. What happens if you change technologies in the future? You do not want to have to change all your URLs. For more thoughts on this see Cool URIs Don’t Change by Tim Berners-Lee.
Securing PHP Through Good Coding Practices
Once you have secured your base PHP installation by configuring php.ini, you should look at your code itself. The other method of securing PHP is to implement good coding practices. There are a number of coding practices to use and many to avoid. We are going to look at a few categories where good coding practices can secure your PHP code. Feel free to comment with other methods as well.
Controlling POST & Form Submissions
Form spoofing is a common exploit on web sites. Form spoofing is when someone makes a submission to your form from somewhere you did not expect. Typically this is done by crafting a POST request and sending it to the URL in the action attribute of your form. Most often, form spoofing is harmless but annoying such as when spammers use scripts to submit spam to the script that processes your contact form. However, form spoofing can be dangerous. Some developers feel that using selects on an HTML form can limit user input. They then do not validate the user input because they believe that the form has done the validation for them. This can be dangerous if someone submits to your script without using your form. They are no longer limited to the choices you provided.
One way to protect against form spoofing is to use a one-time token. Generate a random token and store it in your session. Then using a hidden input field send the one-time token as part of your form. When you process the form, compare the token in the session to the token on the form. If they match, process the form and if they don’t, present an error message. Clear the token from the session after processing so that it is truly a one-time token.
One-time tokens are not one hundred percent. Hackers can still lift the token and use it to submit to your form from another site. However, it is an extra hurdle to overcome. As a result, they are more likely to pick easier targets rather than make the effort to code around your tokens. Even if you use a token system, always validate your input when processing forms just to be on the cautious side.
Protecting Your Databases
Your databases have important information in them. You want to guard these carefully by using good coding practices. In particular, you should not use dynamic SQL statements that are based on user input. This creates a real opportunity for malicious users to send invalid data to your database. Sometimes, you have to utilize user input in a SQL query. When you do, make sure you validate any user input before using it in a query. If your database is MySQL, you can utilize mysql_real_escape_string(). This function will remove invalid characters, effectively sanitizing user input. If your code relies on the PHP magic_quotes_gpc functionality, now is the time to re-purpose your code. This functionality will be deprecated in PHP version 6.
Securing PHP takes some diligence, which a bit of PHP training can help with. There are two main areas where PHP can be secured. You can use php.ini to control the settings for your PHP installation. There are a number of settings that can lead to a more secure PHP environment. Once your PHP installation is secure, use good coding practices to write secure code. There are a number of techniques for writing secure code. Share some of your favorites in the comments.
Help us spread the word!
If you liked this article, consider enrolling in one of these related courses:
|Jul 23-24||Web Development with PHP/MySQL|
|Sep 17-18||Web Development with PHP/MySQL|
|- Classroom - Online|