views:

1021

answers:

4

In PHP 5.2 there was a nice security function added called "input_filter", so instead of saying:

$name = $_GET['name'];

you can now say:

$name = filter_input (INPUT_GET, 'name', FILTER_SANITIZE_STRING);

and it automatically sanitizes your string, there is also:

  • FILTER_SANITIZE_ENCODED
  • FILTER_SANITIZE_NUMBER_INT
  • FILTER_SANITIZE_EMAIL
  • FILTER_SANITIZE_URL

etc. so this is a very convenient security feature to use and I want to switch over to it completely.

The problem is... I often manipulate the $_GET and $_POST arrays before processing them, like this:

$_GET['name'] = '(default name)';

but it seems that filter_input does not have access to the changes in $_GET since it reads "INPUT_GET" which is of type int (?). It would be nice if I could get filter_input to read $_GET instead but:

$name = filter_input ( $_GET, 'name', FILTER_SANITIZE_STRING );

gives me the error:

Warning: filter_input() expects parameter 1 to be long, array given.

Can anyone think of a way that I could:

  • manipulate the source of INPUT_GET (whereever it is) so that I can change its values before filter_input can read them
  • get filter_input to read $_GET

ADDENDUM:


Rich asked: "Why are you changing the arrays anyway, surely you want them to be an input, rather than something you've programmatically inserted."

It is just a very convenient place to preprocess variables coming in, e.g. in order to:

  • set defaults (if $_GET['state'] = '' then $_GET['state'] = 'AL')
  • do manual processing (delete all spaces, etc.)
  • security (some of which will be done by filter_input now)

Then I know by the time I get the incoming variable, it is secure and valid. Of course I could copy the $_GET array to another array and process THAT array but that is just an unnecessary step since I $_GET is already a functioning array so it makes sense to do it with these system arrays that already exist.

A: 

If you are manually changing the array, surely you don't need to sanatise it anyway? Why are you changing the arrays anyway, surely you want them to be an input, rather than something you've programmatically inserted.

Perhaps more code/context would be helpful.

Rich Bradshaw
+1  A: 

The INPUT_GET bit is just an identfier (number) telling PHP that it needs to get the value from $_GET.

If you want to use filter_input on the entire array, you need to loop through it, send each array key to filter_input, and put the result back in $_GET.

It'll probably be just as easy to just write a function that does the sanitizing yourself, and that should also allow you to deal with arrays in arrays (it doesn't look like filter_input will do that). There are a couple of these sample functions in the PHP.net documentation comments, doing stuff like removing "magic quotes". See here for an example.

Michael Madsen
+6  A: 

You could manually force it to read the arrays again by using filter_var and filter_var_array

$name = filter_var ( $_GET['name'], FILTER_SANITIZE_STRING );
Simon
That's it, thanks!
Edward Tanguay
A: 

A handy way to do this without modifying the global array:

if (!($name = filter_input(INPUT_GET, 'name'))) {
    $name = 'default_value';
}

Or using the ternary operator:

$name = ($name = filter_input(INPUT_GET, 'name')) ? $name : 'default_value';
Jrgns