Make PHP’s $_POST data more secure

PHP is a great programming language, but it is not a framework like many of the newer “languages” and as such its basic functions are not as secure as required in a modern web application. Trusting PHP’s $_POST is risky but we have functions that can help make PHP’s $_POST data more secure. This is done by using a few of PHPs functions to get and filter the variable data and provide it in a somewhat more secure manor.

Web application security, nowadays, is quite different to when PHP first started as “Personal Home Page” and you need to ensure that any “web application” published is as secure as possible. Using Posted data (via $_GET or $_POST) directly without filtering is not a good idea in almost any situation. There are a few exemptions where we think this is acceptable, and we cover this below.

So we are providing an alternative function to the $_POST variable, which returns the same data after we make PHP’s $_POST data more secure by filtering (sanitizing) it for naughty stuff. Explanations are below, but here is the function …

Function to make PHP’s $_POST data more secure

function Input_Post($par, $parType = '')
{
	if($parType == '')
	{
		$parType = gettype($par);
	}
	$return = '';
	switch ($parType) {
		case 'email':
			$return = filter_input(INPUT_POST, $par, FILTER_SANITIZE_EMAIL);
			break;
		case 'int':
			$return = filter_input(INPUT_POST, $par, FILTER_SANITIZE_NUMBER_INT);
			break;
		case 'float':
			$return = filter_input(INPUT_POST, $par, FILTER_SANITIZE_NUMBER_FLOAT);
			break;
		case 'double':
			$return = filter_input(INPUT_POST, $par, FILTER_SANITIZE_NUMBER_FLOAT);
			break;
		case 'url':
			$return = filter_input(INPUT_POST, $par, FILTER_SANITIZE_URL);
			break;
		default: // 'string'
			$return = filter_input(INPUT_POST, $par, FILTER_SANITIZE_STRING);
			break;
	}
	if($par != $return)
	{
		//Log error to SQL and ban if more than predefined amount of errors in predefined amount of time ...
	}
	return $return;
}

Explanation

The function name should be short and succinct. we think input_post() is about as good as we need it, but you may also like _post().

We also need two parameters ($par & $parType) in some situations, to check for email addresses for example.

Next we need to make the second parameter $parType optional and check the type of the first variable (using gettype()). This is important to ensure we are providing the correct type of sanitizing and filtering of the input data so we do not filter any important data out and filter any harmful data.

Now comes the critical part, sanitizing any data based on the type and storing that in $return variable.

Using a switch (or case) is more efficient than if/elseif when dealing with many options and it just looks better.

Last test is if the return data $return is different to input data $par (eg, if we did any filtering / sanitizing), then we can call a logging function to ensure this is logged for auditing / banning users (we run functions that log to an SQL table and check how many failures in X days for this session footprint), but this is beyond the scope of this post.

Then, return the filtered data $return.

Implementation

Using STG’s Input_Post() function is as simple as replacing occurrences of:
$_POST[‘variable’]
with
Input_Post(‘variable’)

Exceptions

As stated above, there are exceptions to when you can use $_POST variables directly. We only use submitted data directly when testing, such as if it equals a value:

if($_POST['me'] == 'you') 
{
echo 'you';
}
elseif($_POST['me'] == 'me')
{
echo 'me';
}
else
{
echo 'you and me';
}

Unless you make PHP’s $_POST data more secure, you should NEVER EVER trust any $_GET or $_POST variable as trusting PHP’s $_GET is risky and using it directly should be avoided. We rather using submitted data to make decisions from.

Make PHP’s $_GET data more secure

PHP is a great programming language, but it is not a framework like many of the newer “languages” and as such its basic functions are not as secure as required in a modern web application. Trusting PHP’s $_GET is risky but we have functions that can help make PHP’s $_GET data more secure. This is done by using a few of PHPs functions to get and filter the variable data and provide it in a somewhat more secure manor.

Web application security, nowadays, is quite different to when PHP first started as “Personal Home Page” and you need to ensure that any “web application” published is as secure as possible. Using Posted data (via $_GET or $_POST) directly without filtering is not a good idea in almost any situation. There are a few exemptions where we think this is acceptable, and we cover this below.

So we are providing an alternative function to the $_GET variable, which returns the same data after we make PHP’s $_GET data more secure by filtering (sanitizing) it for naughty stuff. Explanations are below, but here is the function …

Function to make PHP’s $_GET data more secure

function Input_Get($par, $parType = '')
{
	if($parType == '')
	{
		$parType = gettype($par);
	}
	$return = '';
	switch ($parType) {
		case 'email':
			$return = filter_input(INPUT_GET, $par, FILTER_SANITIZE_EMAIL);
			break;
		case 'int':
			$return = filter_input(INPUT_GET, $par, FILTER_SANITIZE_NUMBER_INT);
			break;
		case 'float':
			$return = filter_input(INPUT_GET, $par, FILTER_SANITIZE_NUMBER_FLOAT);
			break;
		case 'double':
			$return = filter_input(INPUT_GET, $par, FILTER_SANITIZE_NUMBER_FLOAT);
			break;
		case 'url':
			$return = filter_input(INPUT_GET, $par, FILTER_SANITIZE_URL);
			break;
		default: // 'string'
			$return = filter_input(INPUT_GET, $par, FILTER_SANITIZE_STRING);
			break;
	}
 	if($par != $return)
	{
		//Log error to SQL and ban if more than predefined amount of errors in predefined amount of time ...
	}
	return $return;
}

Explanation

The function name should be short and succinct. we think input_get() is about as good as we need it, but you may also like _get().

We also need two parameters ($par & $parType) in some situations, to check for email addresses for example.

Next we need to make the second parameter $parType optional and check the type of the first variable (using gettype()). This is important to ensure we are providing the correct type of sanitizing and filtering of the input data so we do not filter any important data out and filter any harmful data.

Now comes the critical part, sanitizing any data based on the type and storing that in $return variable.

Using a switch (or case) is more efficient than if/elseif when dealing with many options and it just looks better.

Last test is if the return data $return is different to input data $par (eg, if we did any filtering / sanitizing), then we can call a logging function to ensure this is logged for auditing / banning users (we run functions that log to an SQL table and check how many failures in X days for this session footprint), but this is beyond the scope of this post.

Then, return the filtered data $return.

Implementation

Using STG’s Input_Get() function is as simple as replacing occurrences of:
$_GET[‘variable’]
with
Input_Get(‘variable’)

Exceptions

As stated above, there are exceptions to when you can use $_GET variables directly. We only use submitted data directly when testing, such as if it equals a value:

if($_GET['me'] == 'you') 
{
echo 'you';
}
elseif($_GET['me'] == 'me')
{
echo 'me';
}
else
{
echo 'you and me';
}

Unless you make PHP’s $_GET data more secure, you should NEVER EVER trust any $_GET or $_POST variable as trusting PHP’s $_GET is risky and using it directly should be avoided. We rather using submitted data to make decisions from.