2
function Query()
{
    $args = func_get_args ();

    if (sizeof ($args) > 0)
    {
         $query = $args[0];

         for ($i = 1; $i < sizeof ($args); $i++)
                $query = preg_replace ("/\?/", "'" . mysql_real_escape_string ($args[$i]) . "'", $query, 1);
    }
    else
    {
          return FALSE;
    }

我有这样的功能。基本上,我会这样查询:

$this->Query('SELECT * FROM USERS WHERE Username = ? AND Points < ?', $username, $points);

它目前支持已弃用mysql的功能,但适应起来就像在我的班级中替换mysqli一样容易。mysqlmysqli

这是一种依靠 SQL 注入攻击的安全方法吗?每一个问号都会被自动清理mysql_real_escape_string,我以前从未遇到过问题,但我应该mysqli_real_escape_string用于清理吗?

我知道 mysqli 的准备好的语句,但bindParam对每个变量使用对我来说似乎有点矫枉过正。

你怎么看?

4

3 回答 3

2

使用绑定参数并不过分,应该是必需的。它将更有效地转义并准备您的参数。

$stmt = mysqli_prepare($link, "INSERT INTO CountryLanguage VALUES (?, ?, ?, ?)");
mysqli_stmt_bind_param($stmt, 'sssd', $code, $language, $official, $percent);

$code = 'DEU';
$language = 'Bavarian';
$official = "F";
$percent = 11.2;

/* execute prepared statement */
mysqli_stmt_execute($stmt);

这看起来真的是矫枉过正吗?

文档

于 2013-03-13T15:55:54.720 回答
1

今天真是美好的一天——连续第二次尝试创建一个合理的数据库抽象层。

我应该使用 mysqli_real_escape_string 进行消毒吗?

没有。
只是因为这个功能不会清理任何东西。

但是要格式化SQL 字符串文字,这个函数是必须的,不能避免或替换。
因此,您正在以正确的方式使用此函数,仅格式化字符串并无条件地格式化它们。
因此,只要您可以使用 ? 标记以替换实际数据(并且 - 甚至让 nitpick 抱怨空闲 - 只要您使用mysql(i)_set_charset()函数设置 SQL 编码)。

如果有人称您的方法被破坏- 只需要求他们提供完整的证明代码片段以显示特定漏洞。

但是,让我提请您注意一些重要的事情。

  1. 动态 SQL 查询部分不仅限于字符串。例如,这 2 个查询不适用于您的函数:

    SELECT * FROM table LIMIT ?,?
    SELECT * FROM table ORDER BY ?
    

    只是因为数字和标识符需要不同的格式。
    所以,最好使用类型提示的占位符,告诉你的函数,应用哪种格式

  2. 运行查询只是工作的一部分。你也需要得到结果。为什么不早点得到它们,而不用不必要的调用使你的代码变得臃肿呢?
  3. 应该有一种插入文字的方法?在不解析它​​们的情况下标记到查询中。

请看一下我的课程,它建立在与您相同的原则上,但我在上面提到了一些改进。我希望您会发现借用一两个想法很有用或至少值得。

于 2013-03-13T19:33:40.587 回答
0

如果你现在使用 mysqli 而不是 mysql。最好使用mysqli_real_escape_string。请注意参数顺序已被修改。(% 和 _ 仍然没有转义)

于 2013-03-13T16:03:47.030 回答