从用户输入获取字母数字字符串的安全方法? (没有preg_replace)

时间:2016-11-11 20:51:11

标签: php security

我已经阅读了许多关于如何将字符串过滤到"字母数字"的许多其他问题,但所有这些问题都建议使用preg_replace()方法。

根据OWASP

  

函数preg_replace()不应与未经过授权的用户一起使用   输入,因为有效载荷将是eval()'ed13。

     

preg_replace(" /.*/ e"," system('echo / etc / passwd')");

     

反思也可以   有代码注入缺陷。请参阅相应的反射   文件,因为它是一个高级主题。

那么现在如何在没有preg_replace的情况下实现这一目标?

$result = preg_replace("/[^a-zA-Z0-9]+/", "", $_POST['data']);
// Notice the $_POST['data']

4 个答案:

答案 0 :(得分:5)

使用preg_replace()过滤用户输入没问题。您引用的OWASP建议是谈论模式本身不是用户输入。

但是,我说使用过滤输入本身就是一个问题 - 您应该进行验证。如同,请勿接受无效输入。

答案 1 :(得分:2)

  1. 正如其他人所指出的那样,您链接的OWASP漏洞只适用于您评估表达式时,无论如何都不应该这样做。
  2. 根据我的经验,正则表达式对于PHP的内置字符串函数就足够的简单操作非常不满意。字符串函数也更快。
  3. 如果数据无效,那么你不应该过滤它,你应该拒绝它。
  4. 示例:

    $result = ctype_alnum($_POST['data']) ? $_POST['data'] : null;
    

答案 2 :(得分:1)

你可以选择这样的东西:

<?php
$unsafe_input = 'some"""\'t&%^$@!`hing~~ unsafe \':[]435^%$^%*$^#'; // input from user

$safe_input = ''; // final sanitized string

// we want to allow 0-9 A-Z and a-z
// merge and flip so that we can use isset() later
$allowed_chars = array_flip(array_merge(range(0, 9), range('A', 'Z'), range('a', 'z')));

// loop each byte of the string
for($i = 0; $i < strlen($unsafe_input); ++$i)
{
    // isset() is lightyears faster than in_array()
    if(isset($allowed_chars[$unsafe_input[$i]]))
    {
        // good, sanitized, data
        $safe_input.= $unsafe_input[$i];
    }
}

echo $safe_input;

答案 3 :(得分:1)

我们有类似的情况,我们使用以下内容:

if ( ! preg_match('/^[a-z0-9:_\/|-]+$/i', $str))
{

//do your stuff
}