Fixing Common PHP Security Issues

There are many potential holes in most PHP scripts. These holes usually appear as a result of poor coding or accidental exclusion. Thankfully most of these security flaws can be prevented very easily.

Data checking

Always check any data you get from the user. It doesn’t matter if it is the site administrator or a regular user, always check it. The easiest way to check data, in my opinion, is with regular expressions. Regular expressions basically define patterns. You can use them to check if a variable is a legitimate e-mail address, string, number, etc.

Secure your include files!

If you are working on a large project, like a content management system, I would highly recommend putting in some sort of security to prevent direct execution of your included files (via the require() or include() functions or one of their derivative functions. In the content management system that I am working on I implemented a very simple yet powerful security system for include files. It only takes up roughly 5 lines of code all together, so it doesn’t slow down execution time at all.

On the main file (the one that includes the other) I define a variable using the define() function. In the included file I then test if the constant exists via the defined() function inside an if statement. Inside the if statement I use the die function to print out a message like “Critical Error: You cannot run this page directly!”, but you could always get fancy and put something like “Hah, how dare you try to hack me!”

Doing this will help protect any of your included files from direct execution, which is often a major security flaw, even in the most professional PHP applications.

E-mail form checks

If you have a contact form that emails you, definitely put in a check to make sure they enter valid data. Often times malicious users will enter code that will force your script spam people, basically they hijack your script. To prevent this use regular expressions to prevent them from inserting quotes and unneeded characters. Several examples of this can be found on Google.

SQL injection protection

Just like with contact forms you will want to secure ANY AND ALL data that gets sent to a SQL server. Period, no ifs ands or buts. SQL injection is a huge problem and can lead to complete server takeover or corruption which can easily get your hosting contract terminated. Always check your data!

In the content management system I am working on, for most of the data I either add slashes using PHP’s mysql_real_escape_string function, or I convert the data to its html entity equivilent. Doing this makes it almost impossible to do SQL injection attacks, although you can never be 100% safe due to character encoding flaws and such.

Use .htaccess

If your server runs apache then you should definitely use .htaccess files to protect important directories. Here is a quick tutorial that shows you how to password protect the directories. When PHP includes files it uses the filesystem commands, so if the files are protected using .htaccess, PHP just ignores that. This is a great solution to prevent people from viewing important data (plus you can use my idea above under the “Secure your include files!” section).

Another thing you should do is add “Options All -Indexes” to your .htaccess in your root directory. Depending on your host’s configuration your folders’ contents may be viewable if there is no index file in them, doing this command will force Apache to look for index files when a folder is browsed and return a notice if one cannot be found. This prevents users from being able to freely browse your data folders.

Magic quotes

Last but not least… magic quotes. Magic quotes were originally made to help make life easier for us PHP geeks, but sadly it turned out to be a huge security flaw. The main thing you want disabled is an option called “magic_quotes_runtime”, which is in your host’s php.ini file (most hosts have this disabled). magic_quotes_runtime will automatically add slashes to any data returned from databases, text files, etc. Pretty much every form of “magic_quotes” is worthless, because it is not nearly as secure as the mysql_real_escape_string function, at least when dealing with databases.

The other main magic quotes annoyance is magic_quotes_gpc, which will add slashes to data that is sent using POST or GET. Luckily you can add some quick code at the beginning of your script to get rid of the effects of this annoyance:


	//remove slashes from data.
	function stripslashes_nested($v) {
		if(is_array($v)) {
			return array_map('stripslashes_nested', $v);
		}
		else {
			return stripslashes($v);
		}
	}

	if(get_magic_quotes_gpc()) {
		$_GET = stripslashes_nested($_GET);
		$_POST = stripslashes_nested($_POST);
	}

Just remember to use the proper functions to slash your data before entering it into a database.

System()

If you are using the system() function in a way that accepts any user-provided arguments, check the arguments first! Failing to do this can lead to system takeover by malicious users. Just use some regular expressions, for example, to make sure the provided arguments are valid.

Session management

If you use cookies in your PHP script to handle sessions, always check the data. If the cookie holds the username and password of the currently logged in user, then before any main script execution do a quick test to make sure the username and password match those in the database. Failing to do this can allow a malicious user to enter bogus usernames and passwords into a cookie, thus tricking your script into thinking they are logged in.

Last minute pointers

Just remember, when writing a script you should go over your code numerous times and make sure you don’t leave anything there that is borderline secure/insecure. Properly handling data is pretty much the key to writing secure PHP scripts, which is pretty obvious since I wrote “check your data” about 20 times.

Please subscribe, or else I will cry. Do you really want to make a programmer cry?

Leave a Reply

Note: By submitting your comment you agree to this blog's comment policy.

If you want a little icon next to your name - sign up for one at Gravatar.