mysql_real_escape_string对于非常简单的数据库插入是否足够?

时间:2010-10-02 00:26:18

标签: php mysql

示例代码:

$email = "" . $_POST['email'];
$con = mysql_connect("localhost","user","pass")
  or die('Could not connect to database.');
mysql_select_db("face", $con);

// Sanitization step
$sanitemail = mysql_real_escape_string($email);

// Is this safe?
mysql_query("INSERT INTO landing_oct_2010 (email) VALUES ('$sanitemail');");

我想知道,对于这个简单的任务,是否只使用mysql_real_escape_string完全足以防止至少注入式SQL攻击,或者我是否应采取其他预防措施。

我在此示例中收集电子邮件地址的事实是偶然的。如果我知道我正在使用电子邮件地址,我会抛出一个正则表达式和一些DNS检查,并且我已经内置了验证。但是,我想关注手头的一般问题:单一的卫生功能是否足够?

5 个答案:

答案 0 :(得分:3)

是的,这就足够了。嗯,有点。

如果使用得当且一致,mysql_real_escape_string应该足以阻止SQL注入。该函数(与mysql_escape_string不同)将连接的字符集考虑在内,因此它应该适用于任何站点,只要您实际使用正确的字符集进行通信。

但是,在过去,bugs have existed在转义例程中,无论如何都可能导致SQL注入(在适当的条件下)。

更好的选择是对MySQLi库使用参数化查询,因为这样可以完全避免转义。参数化查询基本上通过将数据与查询结构分离来工作,这反过来意味着不可能进行SQL注入。在实现方面,数据库开发人员更难以引入允许SQL注入的错误,因为查询结构是单独给出的。

答案 1 :(得分:0)

是的,这已经足够了。与addslashes()相比,mysql_real_escape_string()知道哪些字符影响MySQL命令。此外,您只需检索并使用数据库中的数据,而无需使用stripslashes()

答案 2 :(得分:0)

我会使用trim去除空格

$sanitemail = mysql_real_escape_string(trim($email));

答案 3 :(得分:0)

是的,总的来说。

但是必须记住一些重要的条件:

  1. mysql_real_escape_string()不是“清理”功能。它不会“清理”数据以使其“安全”,而只是逃避分隔符。因此,分隔符是非常重要的部分。只有处理数据用引号括起来,此函数才有效。否则它什么都没有帮助。
  2. 要使charset魔法工作,应首先调用mysql_set_charset()函数。否则,如果使用多字节编码,而不是utf-8,则此功能无效。

答案 4 :(得分:-3)

据我所知,有一些有用的东西:

    class mysql_db{
        var $connid;

        var $search = array('/union/i', '/load_file(\s*(\/\*.*\*\/)?\s*)+\(/i','/into(\s*(\/\*.*\*\/)?\s*)+outfile/i');
        var $replace = array('union  ', 'load_file   (', 'into   outfile');

        function escape($string){
          if(!is_array($string)) return str_replace(array('\n', '\r'), array(chr(10), chr(13)),mysql_real_escape_string(preg_replace($this->search, $this->replace, $string), $this->connid));
          foreach($string as $key=>$val) $string[$key] = $this->escape($val);
          return $string;
        }
}