【问题标题】:MySQLi prepare with fetch_assoc, or is mysql_real_escape_string ok to use?MySQLi 准备使用 fetch_assoc,还是 mysql_real_escape_string 可以使用?
【发布时间】:2011-12-19 00:26:30
【问题描述】:

我继承了一个中等规模的代码库,它大量使用了 mysql_fetch_assoc 和 mysql_fetch_object,并且没有任何安全预防措施来防止 SQL 注入。我认为这是一件非常糟糕的事情TM 需要修复。

最初,我打算使用 mysqli prepare/bind_param/execute 语句来处理数据库查询。但是,以下方法不起作用:

$stmt = $GLOBALS['db']->prepare('SELECT * FROM Users WHERE Username=?');
$stmt->bind_param('s', $username);
$stmt->execute();

// Somehow retrieve the fetched row as an object (Doesn't work!)
return $stmt->fetch_assoc();

问题 1:有没有办法通过 prepare/bind 使用 fetch_assoc 或 fetch_object?我可以重构所有的代码,但是会很乱而且需要很长时间。

问题 2:如果无法做到这一点,从安全角度来看,使用 mysqli_query() 是否同样有效,前提是所有输入都通过 mysql_real_escape_string() 正确转义?您还有其他建议吗?

【问题讨论】:

    标签: php pdo mysqli


    【解决方案1】:

    用原始 mysli 替换原始 mysql 几乎没有意义。
    事实上,所有那些令人沮丧的重复准备/绑定/执行/获取都像 mysql_query/fetch 一样丑陋。

    如果你无论如何都要重构你的代码,你必须开发一些 library 函数,它将一个查询和它的参数作为参数并返回一个数据数组,在里面完成所有的获取。

    至于通过 mysql_real_escape_string() 转义所有输入,这将相当于魔术引号,最后被认为是一种不好的做法。

    事实上,mysql_real_escape_string() 不会使任何数据安全。它根本与安全无关。它只是一个格式化例程,仅适用于字符串。但是还有其他类型可以插入到查询中。详细解释请参考我之前的回答How to include a PHP variable inside a MySQL insert statement

    【讨论】:

      【解决方案2】:
      1. $row = $stmt->fetch(PDO::FETCH_ASSOC) 参考:http://php.net/manual/en/pdostatement.fetch.php

      2. 如果需要,您可以使用 mysqli。只要您对进入 SQL 语句的所有用户数据(包括您自己的数据)使用 real_escape_string 函数,它就不会比使用准备好的语句更安全 - 只是更容易错过帖子并留下漏洞。

      【讨论】:

      • 看起来是这样,我将不得不使用 PDO 而不是 mysqli,但我认为应该没问题。
      • mysqli 有$result = $stmt->get_result(),它应该返回一个常规的结果集,你可以做一段时间(fetchrow())类型的事情,但我从来没有用过,所以不确定是不是正是你想要的
      猜你喜欢
      • 2016-10-27
      • 1970-01-01
      • 2014-05-18
      • 1970-01-01
      • 2010-11-17
      • 1970-01-01
      • 1970-01-01
      • 2011-08-02
      • 2011-09-08
      相关资源
      最近更新 更多