How to sanitize your php input

2007-11-08

A php class that makes sure your php input is clean

Never trust user input, it may be malicious, always check your php input.

Check all global arrays like $_GET, $_POST, $_REQUEST, $_COOKIE, allow only known variables and make sure that they contain the right type of data.

What does this mean ? It means that if you have a $_GET['id'] variable in your script which has to be an integer, always check it and make sure it is an integer.

Also don't allow other variables in $_GET or other globals, keep only variables that your scripts need. So, if your script only uses only one variable $_GET['id'] then dispose other variables. Here is how I do it.

This is $_GET contents


Array

(

    [id] => blabla77

    [name] => John

    [variable1] => somedata

    [variable2] => somedata

)

This is the sanitize code


//in this example script I use two variables, one integer and one string

sanitize($_GET, array( 'id'=>'int', 'name' => 'str') );

This is $_GET contents after sanitization


Array

(

    [id] => 77

    [name] => John

)

We removed unwanted variables and we made sure that every variable has the correct data type.

Here is the class that I use for santiziation, feel free to improve it to suit your needs.


/*

    Sanitize class

    Copyright (C) 2007 CodeAssembly.com  



    This program is free software: you can redistribute it and/or modify

    it under the terms of the GNU General Public License as published by

    the Free Software Foundation, either version 3 of the License, or

    (at your option) any later version.



    This program is distributed in the hope that it will be useful,

    but WITHOUT ANY WARRANTY; without even the implied warranty of

    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

    GNU General Public License for more details.



    You should have received a copy of the GNU General Public License

    along with this program.  If not, see http://www.gnu.org/licenses/

*/

/**

 * Sanitize only one variable .

 * Returns the variable sanitized according to the desired type or true/false 

 * for certain data types if the variable does not correspond to the given data type.

 * 

 * NOTE: True/False is returned only for telephone, pin, id_card data types

 *

 * @param mixed The variable itself

 * @param string A string containing the desired variable type

 * @return The sanitized variable or true/false

 */



function sanitizeOne($var, $type)

{	

	switch ( $type ) {

			case 'int': // integer

			$var = (int) $var;

			break;



			case 'str': // trim string

			$var = trim ( $var );

			break;



			case 'nohtml': // trim string, no HTML allowed

			$var = htmlentities ( trim ( $var ), ENT_QUOTES );

			break;

			

			case 'plain': // trim string, no HTML allowed, plain text

			$var =  htmlentities ( trim ( $var ) , ENT_NOQUOTES )  ;

			break;



			case 'upper_word': // trim string, upper case words

			$var = ucwords ( strtolower ( trim ( $var ) ) );

			break;



			case 'ucfirst': // trim string, upper case first word

			$var = ucfirst ( strtolower ( trim ( $var ) ) );

			break;



			case 'lower': // trim string, lower case words

			$var = strtolower ( trim ( $var ) );

			break;



			case 'urle': // trim string, url encoded

			$var = urlencode ( trim ( $var ) );

			break;



			case 'trim_urle': // trim string, url decoded

			$var = urldecode ( trim ( $var ) );

			break;

			

			case 'telephone': // True/False for a telephone number

			$size = strlen ($var) ;

			for ($x=0;$x<$size;$x++)

			{

				if ( ! ( ( ctype_digit($var[$x] ) || ($var[$x]=='+') || ($var[$x]=='*') || ($var[$x]=='p')) ) )

				{

					return false;

				}

			}

			return true;

			break;

			

			case 'pin': // True/False for a PIN

			if ( (strlen($var) != 13) || (ctype_digit($var)!=true) )

			{

				return false;

			}

			return true;

			break;

			

			case 'id_card': // True/False for an ID CARD

			if ( (ctype_alpha( substr( $var , 0 , 2) ) != true ) || (ctype_digit( substr( $var , 2 , 6) ) != true ) || ( strlen($var) != 8))

			{

				return false;

			}

			return true;

			break;

			

			case 'sql': // True/False if the given string is SQL injection safe

			//  insert code here, I usually use ADODB -> qstr() but depending on your needs you can use mysql_real_escape();

			return mysql_real_escape_string($var);

			break;

		}	

	return $var;

	

}





/**

 * Sanitize an array.

 * 

 * sanitize($_POST, array('id'=>'int', 'name' => 'str'));

 * sanitize($customArray, array('id'=>'int', 'name' => 'str'));

 *

 * @param array $data

 * @param array $whatToKeep

 */



function sanitize( &$data, $whatToKeep )

{

	$data = array_intersect_key( $data, $whatToKeep ); 

	

	foreach ($data as $key => $value)

	{

		$data[$key] = sanitizeOne( $data[$key] , $whatToKeep[$key] );

	}

}

You can also use php filter to implement your sanitization code, just add new data types to the above class using php filter.

Share this with the world

Related

Comments

John Smith

What would be the best way to add sanitisation for email addresses to this code?

Posted on 2008-03-08 21:05:39
Phil

It would be nice to add a check for valid email address something like...

<pre>
<code>
function validate_email_address ($address)
{
// check address format
$address = stripslashes($address);
if (!ereg ("^.+@.+\\\\..+$", $address) || empty ($address)) return FALSE;
if (eregi ("\\r", $address) || eregi ("\\n", $address)) return FALSE;

// safe
return TRUE;
}
</code>
</pre>


Regards,
Phil

Posted on 2008-03-21 20:02:43
John Smith

What would be the best way to add sanitisation for email addresses to this code?

Posted on 2008-03-08 21:16:53
mitch

Is there a reason, or is it just preference, that you passed a ref to $_GET to the sanitize function? I would probably have just returned a new array. Does it matter? Is one way more efficient or better, or not?

Posted on 2009-09-10 22:29:10
rocket

why creating another array, when there is actually one you could already use.
but even more important: This way you could possibly secure scripts which are already there but more or less unsecure..

Posted on 2010-04-07 21:43:18
Smith John

You seem to have a misunderstanding on what a class is. That is not a class, those are two individual functions.

Posted on 2010-08-31 22:40:23
Bren

Hi there!

I've used yor functions (thanks a lot!) I've also added in strip_tags to the nohtml (which is actually the only one I'm really using in this case).

Posted on 2010-11-23 23:54:02
Amil

What about adding this kind of sanitizing to your business logic handling codes?

For example $user->SetId($_POST['id']) should be doing all the validations and sanitizing.

Posted on 2011-01-03 04:48:39
dancingbears

<?php

$email = "example@email.com";

if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE)
{
echo $email." is invalid";
}
else
{
echo $email." is valid";
}

?>


this is the best way to check for emails. its a treat.

Posted on 2012-08-22 05:00:30

Make yourself heard

Categories

Subscribe

All Posts

All Comments

© Copyright CodeAssembly

All code is licensed under LGPL, unless otherwise noted

littlebubu