1

从久违的剧本回到剧本后,我陷入了一次突然失败的清理工作。
我在过滤器意外返回中发现了问题false

这是一个复制我的意外结果的示例:

$test = [ 'apple', 'bananna', 'orange', 'lime', 'grape', ];
var_export( filter_var( $test, FILTER_UNSAFE_RAW ));  // false

我认为这FILTER_UNSAFE_RAW应该只是返回输入(在这种情况下是一个数组)不变。
我的理解/方法错了吗?

注意:
我的代码必须严格自力更生并且尽可能轻量级,因此我只是在需要的地方编写简单的辅助函数,而不是加载第 3 方库/类。

例子:

$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' ))
    {
        ...

如您所见,这种方法需要bar通过清理,即使不需要清理操作。

我误会了FILTER_UNSAFE_RAW吗?

4

2 回答 2

1

它返回 false 因为filter_var()无法验证数组。filter_var_array()就像运行filter_var()到每个主题数组的值一样。您可以尝试使用数组作为数组bar内的值sanitizeFILTER_UNSAFE_RAW作为过滤器和FILTER_REQUIRE_ARRAY标志

'sanitize' => [ 
    'foo' => FILTER_SANITIZE_EMAIL,
    'bar' =>  [
            'filter' => FILTER_UNSAFE_RAW,
            'flags'  => FILTER_REQUIRE_ARRAY
            ],
],

另一件需要注意的事情是,由于您只使用FILTER_UNSAFE_RAW而不指定标志,因此它什么也不做。所以不消毒也是一样的。尽管它不适用于您的案例,因为它不会传递给验证。

于 2017-12-21T06:16:27.493 回答
1

过滤器标志丢失

看起来您没有为 sanitize 部分添加正确的标志filter_var_array

每当您处理数组时,都必须包含标志FILTER_REQUIRE_ARRAY

因此,没有标志,您得到的响应为false

注意: FILTER_UNSAFE_RAW只是可选地剥离或编码特殊字符。这也是默认过滤器。

例子

$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 ));

输出

Array
(
    [bar] => Array
        (
            [0] => apple
            [1] => bananna
            [2] => orange
            [3] => lime
            [4] => grape
        )

)

编辑工作代码

$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;
}
于 2017-12-21T06:26:23.787 回答