2

目前我有一些数据库包装函数,如下所示:

function db_escape($str) {
    return mysql_real_escape_string($str);
}

function db_query($sql) {
    global $LINKID;
    return mysql_query ($sql, $LINKID);
}

function db_fetch_array($result) {
    return mysql_fetch_array ($result, MYSQL_ASSOC);
}

在我的代码中,我可以执行以下操作:

$result = db_query('SELECT userid, first_name, last_name FROM user 
                    WHERE email = "' . db_escape($email) . '"');

if ($result) {
    $user = db_fetch_array($result);
}

这背后的想法之一是,当我从 mysql 切换到 mysqli 时,只需几分钟即可更新我的包装函数,而且我不必替换数百个实例mysql_real_escape_string()mysql_query()并且mysql_fetch_array()跨数百个不同的项目。

唯一的问题是上面可以很容易地转换为标准的过程 mysqli 函数,但不是准备好的语句。

这有关系吗?似乎每个教程都说准备好的语句对安全性和性能很重要,但是目前:

  1. 我的项目都没有性能问题。
  2. 我非常讨厌将用户输入转换为预期的类型(字符串、整数、浮点数等),并且还手动转义查询中任何地方使用的任何用户输入。

考虑到这一点,是否真的有必要为过去或未来的项目切换到准备好的陈述?

4

2 回答 2

2

我认为你应该考虑长期利益。例如,如果将来您不再是该项目的开发人员,则使用非准备语句的习惯将传递给下一个开发人员,并且:

我非常讨厌将用户输入转换为预期的类型(字符串、整数、浮点数等),并且还手动转义查询中任何地方使用的任何用户输入。

可能不再是真的了。即使你说你很小心,在某些时候你会犯错或忘记(是的,人们这样做了!这就是事情破裂的原因)然后这将是一个问题。

以下面的案例为例。你认为它安全吗?

$id = $_POST['id'];
$result = db_query('SELECT userid, first_name, last_name FROM user 
                WHERE userid = ' . db_escape($id) );
于 2013-09-12T01:31:20.640 回答
0

尽管看到又一位 Smart 先生提出他的Perpetuum Mobile让我感到有些恼火,但我不能说他的想法在某种程度上完全不合理。但是,不幸的是,它们都基于错误的假设。

哪个是

  • SQL 格式化规则仅限于转义和强制转换
  • 所需的任何 SQL 注入保护
  • 这种保护应该应用于用户输入
  • 每个 PHP 应用程序都是小而可观察的
  • 就像在另一个答案中提到的那样,只有一个将所有代码都记在脑海中的开发人员曾经参与过该项目。

但同样,所有这些假设都是错误的。

一旦你重新考虑它们,你就会得出结论,只有参数化的查询才能给你一个保险单。请注意,我说的是使用参数的一般概念,而不是 mysqli 中使用的特定实现。即使使用旧的 mysql ext 也可以实现这一想法。

要考虑的另一件事是代码的美观和大小。看看你现在有什么

$result = db_query('SELECT userid, first_name, last_name FROM user 
                    WHERE email = "' . db_escape($email) . '"');
if ($result) {
    $user = db_fetch_array($result);
}

以及它可以使用的参数

$sql = 'SELECT userid, first_name, last_name FROM user WHERE email = ?';
$user = db_fetch_array($sql, $email);
于 2013-09-12T06:28:16.753 回答