We help IT Professionals succeed at work.

Securing data coming in from $_GET & $_POST super globals

gautam_reddyc
on
Hello I have an application which would receive data as input both from $_GET & $_POST arrays. Presently the only method I am using to secure data going to database is through mysql_real_escape_string. Rather than that, I do not use any other filtering. The application is basically for intranet purposes, so security isn't supreme, but just to be safe, I would like to know if there could be any security measures that I should take, for filtring data.
Comment
Watch Question

What version of PHP are you using?  (This changes the answer)

If using v5, you can use functions documented here
http://www.w3schools.com/PHP/php_ref_filter.asp

If using v4, you can use many of the string functions documented here
http://www.w3schools.com/PHP/php_ref_string.asp

strip_tags() is a good candidate and your version can be as old as 3.
Most Valuable Expert 2011
Top Expert 2016
Commented:
You might want to consider the "filter_var" functions, but more importantly, adopt the strategy to "use only known good values."  Example: You expect a number between one and ten.  Check for that!

You can find all kinds of filter examples around the internet.  Regular expressions are often good ways to filter external input.

BTW, though not specifically related to your question, if you take external input and keep it in your data base, then you must filter the contents of your data base, as well as the GET and POST vars.  At some level the same is true for $_COOKIE.

One of the precautions I like to take goes like this... Create an array of variables and function names.  If the external input contains a key that is not in the array, it is bogus input and I reject it.  As each variable is accepted, I pass it to the function, which filters the value and returns either a good (clean) data field or FALSE if the data failed validation.  This method is fairly safe (assuming your filter functions are good) and easily extensible.

Best regards, ~Ray
Ray makes a good clarifying point.  Here's some v5 code that might help...

In the example, I don't try to clean up the e-mail.  My intent is to reject the form submission if someone entered garbage.



function SanitizeInput ( &$Clean, $Process )
{
  $eMailGood = filter_var ( $_POST [ 'eMail' ], FILTER_VALIDATE_EMAIL );

  $Clean [ 'FirstName' ] = filter_var ( $_POST [ 'FirstName' ], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH | FILTER_FLAG_ENCODE_AMP );

  $Clean [ 'LastName' ] = filter_var ( $_POST [ 'LastName' ], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH | FILTER_FLAG_ENCODE_AMP );

  return ( $eMailGood );

} // SanitizeInput()


// Code fragment

  $Clean = array();

  $Good = SanitizeInput ( $Clean, $Process );

// If $Good, I'll process the data.  If ! $Good, I'll present the user with the form again.

Open in new window

Note: filter_var requires PHP v5.

Author

Commented:
@hmmcurdy.

Could you give an overview of what FILTER_SANITIZE_STRING AND FILTER_FLAG_ENCODE_AMP do?? Also, I use a lot data as links, so a lot of data navigation occurs through $_GET array. Would the above example for cleaning data be good.
Actually, what I gave you is a bit wrong in that I stripped out the code that makes sure the variable is indeed set before I posed the example.  Here's an example of GET for you

$Name  = filter_input ( INPUT_GET, 'name', FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH );

FILTER_SANITIZE_STRING tells the filter_input function to remove tags.
FILTER_FLAG_ENCODE_AMP will encode the & as &

Filtering matters if you ever think the data you've captured will end up displayed on a web page.

You don't want someone to successfully store data like <script> redirect the user to another website </script> and then later attempt to display that.
 
In addition to everybody else's comments.....

Since many XSS attacks depend on inserting javascript into the URL then always run strip_tags on ANY field which is not suposed to contain HTML

Another thing to consider is never use a SWITCH statement that lacks a default clause and only code for correct values in your CASE statements. For instance, if a field can only have A, B or C as values then

switch( $anExternallySuppliedValue ) {
     case "A": ....... code
              break;
     case "B": ....... code
              break;
     case "C": ....... code
              break;

     default: // some suitable option... perhaps die() or exit()
}

Always "quote" numeric fields in SQL

mysql_query("select * from myTable where var='123'  ");

and always run data through mysql_real_escape_string before database insertion (see http://www.php.net/mysql_real_escape_string for more info)
BTW, don't trust the $_SERVER or $_COOKIE arrays either. They are injectable as well.
BTW, don't trust the $_SERVER or $_COOKIE arrays either. They are  injectable as well.

Quite right.  Don't trust anything that comes from outside the program.  Even if you (the author) trusts the other employees, learning how to filter data well could help you in some future job.
Most Valuable Expert 2011
Top Expert 2016

Commented:
The filters are described in the links from this page:
http://us2.php.net/manual/en/filter.filters.php

HTH, ~Ray

Author

Commented:
hey thanks for all comments, I do not post the submitted data directly. I have a javascript function that is triggered onsubmit. And this function(pre-processing) directly gets everything from the form, appends data into a string and the string is posted directly to PHP, and not the values alone. Now to get back the values, I have a few functions performing some post-processing to retreive and arrange data in required format, making it easy to store it in database.

So if we are talking about XSS and use of strip_tags, is it fine if I strip tags after my post-processing or would it still affect my application while it is performing the pre-processing steps, making it ready to post?? I hope my question is clear, and not too complex.
Most Valuable Expert 2011
Top Expert 2016

Commented:
Here is the central issue, and it is one you have to handle, because without a detailed review of all of your code (an expensive process) you are the only one who can tell...

Are you "trusting" any external input?  If you are, you're at risk.  All that JavaScript stuff is nice, but the only place you can do safe validation and filtering is on the server after the data is submitted, full stop.

best regards, ~Ray

Author

Commented:
you hit the nail on head!! thanks a lot Sir!!

Author

Commented:
Thanks!