一个更好的SQL字符串清理功能


A better SQL string sanitization function

我目前使用下面的函数来消毒我的$_POST和$_GET对SQL注入。不幸的是,我不能通过它发送代码,例如:"<a href test"。Twitter是如何做到的呢?

 function _secinput($variable)
 {return filter_var(mysql_real_escape_string($variable), FILTER_SANITIZE_STRING); }

另外,谁能告诉我我是否可以在任何方面改进它?

永远不可能也永远不会有一个函数来清理所有的东西。你必须为这项工作选择合适的工具。

1) htmlspecialchars($var,ENT_QUOTES)适用于大多数xss。

2)参数化查询库如PDOMySQLi对sql注入效果最好。

对于CRLF injection,只需删除新行:str_replace("'n","",$var)

4)命令注入使用escapeshellarg()

还有许多其他形式的注射。

我只是想防止SQL注入

即使只是针对sql注入,你也不能"消毒"所有传入的数据(你也不应该)。

即使在这种特殊的情况下,你也不应该完全"净化"你的输入变量。对于查询的不同部分,有不同的规则:您不能像转义数据一样转义标识符。

请看我的答案和完整的解释:https://stackoverflow.com/a/8255054/285587

这取决于你想做什么。如果您希望能够安全地在HTML页面中显示HTML字符,则需要对它们进行转义—FILTER_SANITIZE_SPECIAL_CHARS可以做到这一点(请参阅此处了解更多详细信息)。

我使用了一个函数来提供基于上下文的多种形式的清理。正如人们所提到的,没有一种方法可以清除所有类型的内容。你可以使用这个或类似的东西,并在此基础上构建以满足你的需求:

function sanitize($var, $type)
{
        switch($type) {
                case 'html':
                        $safe = htmlspecialchars($var);
                        break;
                case 'sql':
                        $safe = mysql_real_escape_string($var);
                        break;
                case 'file':
                        $safe = preg_replace('/('/|-|_)/','',$var);
                        break;
                case 'shell':
                        $safe = escapeshellcmd($var);
                        break;
                default:
                        $safe = htmlspecialchars($var);
        }
        return $safe;
}
下面是在SQL查询中使用

的一个示例:

$query = sprintf("SELECT firstName FROM users WHERE userName = '%s'",
                 sanitize($_GET['userName'],'sql'));

在HTML输出中的用法:

<h1>Welcome <?php echo sanitize($firstName,'html');?></h1>

filter_var在很多层面上都失败了,所以我建议你这样做

使用这个

  1. strip_tags($var);
  2. $sanitized_string = (get_magic_quotes_gpc()) ? $var : mysql_real_escape_string($var);
  3. //如果使用MySQL
    $var = mysql_real_escape_string($var);

注意:magic_quotes_gpc特性在PHP 5.3.0中已被弃用。