Monday, July 20, 2009

PHP Security Tips

Having worked with PHP for a number of years I am still at times shocked at how little some developers know about the security implications of their code or how they may be inadvertently compromising their applications by coding a certain way. This articles focusses on some aspects of PHP coding and what to look out for while you are developing to help make your application as secure as possible.

The following tips I have arranged in order of what I feel can be the most dangerous. If anyone has any comments please feel free to post them up and share with everyone else.

1. Command line commands

PHP has a great amount of power, and that power extends to the servers command line itself, allowing you to execute shell commands to the server directly from within the script you are coding. I have seen some coders liberally pepper their code with the shell_exec() function or equivalent PHP functions without a seeming care for what they may be opening up.

My first tip here ... don't use these functions! That's right, if you have no critical need to actually run a command on the servers shell then just don't do it. Rather take the time to figure out another way, rather than potentially open up your server to an attack through this vector.

Now granted that there are numerous ways that the server itself can be setup, as far as PHP's rights as a user to access certain server functions, and these should be enabled anyway. These are topics for a system admin and so are out of scope of this article, but why run the risk anyways.

Secondly, if all other options are exhausted and you absolutely have to use the shell, then please remember to clean up all data being run. As an easy way to clean, you can use PHP's own escapeshellarg() function which can clean some obviously shell-like stuff from any input, but this is also not good on its own.

Another tactic is to avoid using user submitted data as part of the shell argument. For example you can let a user choose from a few options and then run a corresponding argument in shell that was pre-written, rather than add a users submitted data in the argument.

2. Variable variables

Like shell commands above, just don't use them! They are a very big potential risk security-wise and there is almost always an alternate method to using a variable variable. For those who are not sure what I mean, PHP has the ability to create variables based on the value of another variable, for example:

$foo = bar;
$$foo = "Hello";
echo $foo.'\n';
echo $bar.'\n';
echo $$foo.'\n';

What would be echoed is:


Now imagine a hacker figures this out and is able to submit user data to overwrite one of your own variables with his value and so compromise your system. The consequences, depending on where its been used, can be very dangerous.

Other ways to make using this more secure? There aren't any. Just don't use them!

3. Clean, clean, clean those submitted values

We all know the $_SERVER, $_COOKIE, $_GET and $_POST server variables. Those oh so convenient variables that store all that lovely URL and form data that a user submits. But it is shocking how many developers go straight from using that user input as is! Values submitted in URL's and forms by hackers is the number ONE vector of attacks on web applications and therefore should get the biggest attention when you are developing applications. Great PHP frameworks like symfony will escape arguments from forms and URL's as a matter of course and are therefore great, but this doesn't mean you are still safe.

SQL injection is the biggest attack through form submission and is really quite preventable. Functions such as mysqli_real_escape_string() are great for ensuring that posted data is escaped properly before it hits the database query level.

Another to check for, and this applies to framework users as well, is to properly validate your data. Frameworks can do some basic checking on data but are not complete as they tend to be very generic, validating for the sake of "is it a string", "is it x characters long", "is it an email address" etc. Fields like First Name in a form for example can be validated further. Does the name have any spaces? If so, it is incorrect. Does it have any numbers? If so it is invalid. Again, these just help prevent any possible vectors of attack.

These are just a few of the very large security risks to keep a look-out for while developing. While this isn't a complete guide by any stretch of the imagination on PHP application security, hopefully people may find the information here useful.

If you have any comments or extra tips to share, feel free to add your comment.

1 comment: