可以通过转义数据库条目的输入进行SQL注入吗?

时间:2013-05-15 16:22:12

标签: php mysql sql sql-injection

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

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

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

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

有时候稍后需要在另一个脚本中使用列测试的值,并且需要将值插入到其他位置。

因此选择了该列,然后插入。

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

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

2 个答案:

答案 0 :(得分:2)

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

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

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

在第二种情况下,test列可能有撇号。这已经足够糟糕,但如果它来自用户输入更糟糕的话。你可能会受到全面的攻击。<​​/ p>

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

答案 1 :(得分:2)

这个问题的答案很大程度上取决于函数$ db-&gt; escape的作用。我的猜测是它只是清理传入的变量,以便它们对输入“安全”?如果是这样,您在第二个查询中仍然容易受到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。 This topic here非常值得一读。