I’ve just read ‘em on PHPTalk, I don’t visit there every often, but still looking for some interesting articles. And the topic now is using some coding techniques to secure your PHP app in a shared hosting environment.

I’ve trimmed the post for some parts we don’t need to read (such as server’s configurations). We focus on the coding techniques only. Although these issues have been talking for bunches of times over the Internet but there are still some basic things that programmers got missed.

(Reference: http://www.phptalk.com/forums/index.php/topic,6455.0.html)

Since its inception in 1994 as a set of basic development components, PHP has grown into one of the web’s most powerful development engines, having since been installed on literally millions of servers worldwide. And although PHP offers both the versatility and the built-in functionality to run in a reasonably secure fashion, most of those servers are configured in such a way that PHP scripts are at high risk for compromise.

[...]

General practices for PHP application security

At this point, I’d like to briefly go over just a few coding techniques you can use to increase the security of your application. Please understand that this is by no means a comprehensive list, and simply adhering to the suggestions below does not ensure that your application is secure. However, you should make it a point to be security conscious when writing code, rather than trusting your environment to eliminate or mitigate any potential attacks on your application.

1. Sanity-check your data

- This is probably the simplest and most effective way of preventing exploits in your application. Sanity checking just means that if you’re expecting the user to enter a number, make sure you actually received a number. If you’re expecting a string with alphanumeric characters only, verify that that’s what you got. Also, never trust this kind of validation to javascript only, as javascript can easily be disabled on the client side. Finally, never pass user data directly to an SQL query without validating it first. While PHP’s magic_quotes mechanism is great for helping to prevent SQL injection attacks (an attack where a user can enter data in such a way as to run their own arbitrary queries), again you should not rely exclusively on the environment for your application security.

2. Check the type and extension of uploaded files.

- Allowing file uploads is inherently risky, but very often it’s a necessary part of an application. PHP allows you to gain a lot of information about uploaded files before they’re ever written to their final destination, so make use of the information contained in the $_FILES array to ensure that you’re getting the type of file you’re expecting. A basic way of validating the file type is simply to ensure that the extension of the file indicates that it is (or is purported to be) the type of file you’re expecting. A common exploit for upload scripts is for an attacker to upload a malicious PHP script to your site, then browse to the uploaded script to gain control of your files. Even a basic check to make sure that, for instance, only files with a .jpg extension are allowed to be uploaded would prevent this type of exploit. However, I also recommend verifying the MIME type of the file, which is contained in the $_FILES array under the key ‘type’, and will look like: “image/jpeg” or “application/pdf”. Be as restrictive as possible – rather than validating against a list of extensions that are NOT allowed (php, exe, etc), check to make sure that the extension and/or MIME type matches a small group of file types that ARE allowed.

3. Use a .php extension for ALL files with PHP code contained in them.

Often I come across files in PHP projects that have a .inc extension, because they are meant to be included, not browsed to directly from the web. This is a common condition, but there’s a potential security issue here if those files contain any sensitive data (e.g. database passwords). Because .inc files are not parsed by the PHP interpreter, they can be passed directly to the client side if they’re available via a web request, which would allow anyone to read the php code directly. Hopefully the directory these files reside in is denied read access by webserver rules (see below), but even so, there’s no sense in risking an accident where the user ends up being able to browse directly to the file. Use .inc.php.

4. Make use of your webserver’s access control rules (e.g. .htaccess)

- Even if all the php files in your application have a .php extension as discussed in #3, you should still make use of your HTTP server’s access control to prohibit any files in sensitive directories from being served via the web. For instance, if you keep your database passwords in “include/db.inc.php”, this file, and all files in the include/ directory should be prevented from being served via the web. Even though the .php extension will ensure that client-side users can’t read the code if the PHP interpreter is functioning, there is the potential condition that the HTTP server has loaded without the PHP interpreter. Botched upgrades or configuration errors can sometimes cause this condition, and in the event that someone browses to a PHP file without the PHP interpreter ever having been loaded, they will again see the code just as you do when editing the files. In Apache, disabling directory access is usually as simple as creating a file called .htaccess (note the leading period) in the directory, then adding the line: “Deny from All” (no quotes) to that file and saving it.