mysql_real_escape_string还不够好?

时间:2011-03-14 20:56:37

标签: php mysql mysql-real-escape-string

因此,即使使用mysql_real_escape_string

清理数据,使用%27也可以进行SQL注入
%27) SQL INJECTION HERE %2F*

怎么办?

使用示例编辑:

$sql = sprintf("SELECT *, MATCH(post) AGAINST ('%s*' IN BOOLEAN MODE) AS score FROM Posts WHERE MATCH(post) AGAINST('%s*' IN BOOLEAN MODE)",
                mysql_real_escape_string($_GET['searchterm']),
                mysql_real_escape_string($_GET['searchterm']));

$results = $db->queryAsArray($sql);

如果您将%27) SQL INJECTION HERE %2F*传递给searchterm查询字符串,我会在页面上输出:

  

您的SQL语法有错误;   检查对应的手册   您的MySQL服务器版本   正确的语法在'BOOLEAN附近使用   MODE)'在第1行

感谢大家在db类中找到问题..

4 个答案:

答案 0 :(得分:2)

从方法名称queryAsArray推断,您似乎正在使用this DbBase class from the comments of the MySQL functions manual page。如果是这样,那么query方法会从转义的引号中删除转义字符:

function query($sql, &$records = null){
    $sql = str_replace(array('\\"', "\\'"), array('"', "'"), $sql);
    // …
}

然后,你的例子工作(我简化了)并不奇迹:

$input = "', BAD SQL INJECTION --";

$sql = "SELECT '".mysql_real_escape_string($input)."'";
var_dump($sql);  // string(33) "SELECT '\', BAD SQL INJECTION --'"
//                      everything’s OK ↑

$sql = str_replace(array('\\"', "\\'"), array('"', "'"), $sql);
var_dump($sql);  // string(32) "SELECT '', BAD SQL INJECTION --'"
//                                Oops! ↑

答案 1 :(得分:1)

我们手册中提到的注释已标记为删除。一旦它传播到我们网络中的所有镜像,它将不再显示在官方文档中。

~ Daniel P. Brown
  Network Infrastructure Manager
  http://php.net/

答案 2 :(得分:0)

最好不要构建这样的语句,而是使用mysqli或PDO使用参数查询。这将解决MySQL注入的问题,有一天(不幸的是,它还会更好),因为查询是在没有参数的情况下缓存的,这意味着你只有一个查询在缓存而不是几十个不同的查询,因为单个输入值一直在变化。其他数据库长期以来都在使用它,但是自从最新版本以来,MySQL只是设法不使参数化查询变慢。

%27实际上会终止字符串看起来似乎不合理。看起来更像是在字符串中嵌入引号的可能性,但我不确定。

可以肯定的是,我决定牺牲我的服务器并测试它。当我在输入字段和textarea中输入%27,然后使用mysql_real_escape_string进行转义然后插入数据库时​​,我没有错误。刚刚插入了文本%27。所以没问题。

答案 3 :(得分:-1)

你错了。这里不能注射。

遵循这三个简单的规则

  1. 客户的编码由mysql_set_charset()
  2. 正确设置
  3. 正在转发的数据using mysql_real_escape_string()
  4. 并附在引号
  5. 您可以确定无法注射