0

在开发 PHP 应用程序时,我想到了这种情况:用户在表单中提交某种文本,在服务器端,文本被转义并插入到数据库中。问题是:最后一个查询(使用数据库中的值)中的 SQL 注入是否可能?

示例(我认为我不必解释我的数据库类):

$db->query("INSERT INTO accounts SET test='".$db->escape($_POST["sometext"])."'");

好的,到目前为止我知道什么都不会发生,理论上我也可以用准备好的声明来做到这一点,没有区别。

有时稍后需要在另一个脚本中使用列 test 的值,并且该值需要插入到其他地方。

所以该列被选中,然后被插入。

$db->query("SELECT test FROM accounts WHERE ... LIMIT 1");
$row = $db->fetchRow();
$db->query("INSERT INTO secoundtable SET test='".$row["test"]."'");

如您所见,数据库的值在最后一个 Query 中使用。我必须逃到这里吗?

4

2 回答 2

2

您应该养成始终使用正确参数化查询的习惯。

在第一种情况下,有可能:

  • escape方法有一个错误,导致它在某些地方无法正确转义
  • 代码可能会意外更新以删除escape调用

在第二种情况下,该test列可能有一个撇号。这已经够糟糕了,但如果它来自用户输入,那就更糟了。你的手可能会受到全面攻击。

我认为根本没有任何理由避免准备好的语句/参数化查询。它们更易于阅读、安全(r)、易于重复使用等。

于 2013-05-15T16:29:03.640 回答
2

这个问题的答案很大程度上取决于函数 $db->e​​scape 的作用。我的猜测是它只是清理传入的变量,以便它们对输入是“安全的”?如果是这样,您在第二个查询中仍然容易受到 SQL 注入攻击,这仅仅是因为您信任用户数据。

通过运行脚本自己测试一下:

//First query shouldn't cause you any issues (I'm assuming your function is safe).
$test = "'";
$db->query("INSERT INTO accounts SET test='" . $db->escape($test) . "'");

//Second query will cause you issues because you're taking the single quote from your
//table column and inserting it directly into the last query.
$db->query("SELECT test FROM accounts WHERE ... LIMIT 1");
$row = $db->fetchRow();
$db->query("INSERT INTO secoundtable SET test='".$row["test"]."'");

顺便说一句,如果您想完全安全地抵御 SQL 注入,您应该考虑使用 Prepared Statements。这里的这个话题很值得一读。

于 2013-05-15T16:29:25.030 回答