After returning to a script from a long absence, I'm am stuck on a suddenly failing sanitization.
I found the problem in a filter unexpectedly returning false
.
Here's an example to replicate my unintended results:
$test = [ 'apple', 'bananna', 'orange', 'lime', 'grape', ];
var_export( filter_var( $test, FILTER_UNSAFE_RAW )); // false
I thought that FILTER_UNSAFE_RAW
is supposed to just return the input (an array in this case) unchanged.
Am I wrong in my understanding/approach?
NOTE:
My code has to be strictly self-reliant and as light-weight as possible, so rather than loading 3rd party libraries/classes, I'm just writing-in simple helper functions where needed.
EXAMPLE:
$filters = [
'sanitize' => [
'foo' => FILTER_SANITIZE_EMAIL,
'bar' => FILTER_UNSAFE_RAW,
],
'validate' => [
'foo' => FILTER_VALIDATE_EMAIL,
'bar' => [
'filter' => FILTER_VALIDATE_REGEXP,
'flags' => FILTER_REQUIRE_ARRAY,
'options' => [ 'regexp' => '/(apple|grape)/' ],
],
],
];
$test = [
'malicious' => 'something bad',
'foo' => 'test@ema.il',
'bar' => [ 'apple', 'grape', 'orange', ],
];
// validate
$checked = sanitizeInput( $filters, $test );
// sanitizer
function sanitizeInput( $f, $input )
{
// sanitize
$sanitized = filter_var_array( $input, $f['sanitize'] )
// validate
$validated = filter_var_array( $sanitized, $f['validate'] );
// if anything appears to have failed validation (was set to FALSE)
if( FALSE !== strpos( json_encode($validated), 'false' ))
{
...
As you can see, this approach requires that bar
passes sanitization, even though no sanitizing action is necessary.
Am I misunderstanding FILTER_UNSAFE_RAW
?
It looks like you have not added the proper flags for the sanitize part of the filter_var_array
Whenever you are processing an array, you have to include the flag FILTER_REQUIRE_ARRAY
Hence without the flag, you were getting the response as false
Note: FILTER_UNSAFE_RAW
just optionally strips or encodes special characters. Also this is the default filter.
Example
$test['bar'] = array( 'apple', 'bananna', 'orange', 'lime', 'grape' );
$san['bar'] = [
'filter' => FILTER_UNSAFE_RAW,
'flags' => FILTER_REQUIRE_ARRAY
];
print_r(filter_var_array( $test, $san ));
Output
Array
(
[bar] => Array
(
[0] => apple
[1] => bananna
[2] => orange
[3] => lime
[4] => grape
)
)
Edited Working Code
$filters = [
'sanitize' => [
'foo' => FILTER_SANITIZE_EMAIL,
'bar' => [
'filter' => FILTER_UNSAFE_RAW,
'flags' => FILTER_REQUIRE_ARRAY
],
],
'validate' => [
'foo' => FILTER_VALIDATE_EMAIL,
'bar' => [
'filter' => FILTER_VALIDATE_REGEXP,
'flags' => FILTER_REQUIRE_ARRAY,
'options' => [ 'regexp' => '/(apple|grape)/' ],
],
],
];
$test = [
'malicious' => 'something bad',
'foo' => 'test@ema.il',
'bar' => [ 'apple', 'grape', 'orange', ],
];
// validate
$checked = sanitizeInput( $filters, $test );
// sanitizer
function sanitizeInput( $f, $input ) {
// sanitize
$sanitized = filter_var_array( $input, $f['sanitize'] );
print_r($sanitized);
// validate
$validated = filter_var_array( $sanitized, $f['validate'] );
// if anything appears to have failed validation (was set to FALSE)
if( FALSE !== strpos( json_encode($validated), 'false' )) {}
return $validated;
}