将输入数据清理为适用于Mysql数据库的函数

18

我正在尝试编写一个通用的功能,用于对输入到Mysql数据库中的内容进行过滤。目前为止,这是我所拥有的:

function sanitize($input){
    if(get_magic_quotes_qpc($input)){

        $input = trim($input); // get rid of white space left and right
        $input = htmlentities($input); // convert symbols to html entities
        return $input;
    } else {

        $input = htmlentities($input); // convert symbols to html entities
        $input = addslashes($input); // server doesn't add slashes, so we will add them to escape ',",\,NULL
        $input = mysql_real_escape_string($input); // escapes \x00, \n, \r, \, ', " and \x1a
        return $input;
    }
}

如果我正确理解了get_magic_quotes_qpc()的定义,那么它是由php服务器设置的,可以自动转义字符,无需使用addslashes()
我是否已经正确地同时使用了addslashes()mysql_real_escape_string(),并且有没有其他方法可以增加净化程度。
谢谢。

2
将尽可能多的逃逸函数组合在一起并不是一个好方法。你最终只会得到三倍转义的数据,而且除了用于 HTML 输出之外,无法再做其他任何事情。 - mario
5个回答

34

htmlentities()不必用于使数据安全,以供 SQL 使用。它是用于在输出到 HTML 时避免 XSS 漏洞的数据值时使用的。这也是您需要注意的重要安全问题,但与 SQL 无关。

addslashes()和mysql_real_escape_string是重复的。你会在数据库中的字符串中得到文字反斜杠。

不要使用魔术引号。此功能已经被弃用多年。不要将 PHP 代码部署到启用魔术引号的环境中。如果启用了它,请将其关闭。如果是托管环境并且他们不会关闭魔术引号,请获取新的托管提供商。

不要使用 ext/mysql。它不支持查询参数、事务或 OO 用法。

更新: ext/mysql 在 PHP 5.5.0 (2013-06-20) 中已被弃用,并在 PHP 7.0.0 (2015-12-03) 中被删除。你真的不能用它。

使用 PDO,通过使用准备好的查询来使你的查询更安全。

有关编写安全 SQL 的更多详细信息,请阅读我的演示文稿 SQL Injection Myths and Fallacies


6

魔术引号已经被弃用。如果可以,请关闭它们:)

第二部分的addslashesmysql_real_escape_String做了类似的事情。只需尝试即可。

addslashes( '\\')
// and
mysql_real_escape_string( '\\')

结果应该是\\,因此如果您使用
 mysql_real_escape_string( addslashes( '\\'))

您需要获得\\(或字符串'\\\\')。仅使用mysql_real_escape_string(更好)或addslashes,永远不要同时使用两者。

我建议使用PDO代替原始函数和手动转义。


1
为什么在保存数据到数据库之前要应用htmlentities?如果您想将数据用于除了在浏览器中输出之外的其他用途,怎么办?例如搜索、分区数据、在其他编程语言中使用数据等等...
唯一需要应用的是mysql_real_escape_string(或使用PDO),没有其他东西。
我通常更喜欢完全撤消魔术引号的影响。魔术引号只会让工作变得繁琐,本来就不应该被发明出来。这里有一个从PHP手册中提取的代码片段,可以撤消魔术引号的影响:
if (get_magic_quotes_gpc()) {
    $process = array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST);
    while (list($key, $val) = each($process)) {
        foreach ($val as $k => $v) {
            unset($process[$key][$k]);
            if (is_array($v)) {
                $process[$key][stripslashes($k)] = $v;
                $process[] = &$process[$key][stripslashes($k)];
            } else {
                $process[$key][stripslashes($k)] = stripslashes($v);
            }
        }
    }
    unset($process);
}

0

最糟糕的是,无论使用哪个函数,添加斜杠都不能对任何内容进行消毒处理
并且它根本不应该被用作任何"消毒"手段。

斜杠无法"消毒"数据。斜杠只能转义字符串定界符。因此,您唯一可以谈论的消毒就是转义和引用

否则,如果您不在"消毒"的字符串周围加上引号,那么您将根本没有任何保护。


-5

使用:

mysql_real_escape_string()

这将防止坏数据,如DROP TABLE ;)


2
这是非常无能的回答。mysql_real_escape_string()并不能“防止坏数据”。然而,你无论如何都不能使用mysql扩展来进行查询注入。 - Your Common Sense

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接