准备好的SQL语句与htmlspecialchars转换的GET变量有何不同?

时间:2015-03-05 11:56:57

标签: php security mysqli sql-injection

所以我在我的网站上乱搞SQL注入,试图找到一种简单的方法来保护它免受SQL注入。我发现很多关于"准备好的SQL语句",大部分都在this post

这一切都很好,是的,它确实阻止了我所知道的任何类型的SQL注入,并且还阻止了所有用于测试SQL注入安全性的应用程序。

但是,我发现所有注射都是一样的,那就是使用'引号。我的问题是:当我可以简单地阻止使用htmlspecialchars运行查询时,为什么要使用预处理语句或类似的东西?

示例:

$id = htmlspecialchars($_GET['id'], ENT_QUOTES);
$query = Mysqli_Query($dbc, "SELECT * FROM `Users` WHERE `user_id`='$id'") or die(mysql_error());

通过更改&#39>来防止所有注射。字符为&#039,在MYSQL语句中无效。

我在这里错过了什么吗?人们有没有理由使用准备好的陈述?

2 个答案:

答案 0 :(得分:4)

参数化查询是数据库功能;数据库本身提供了一个API来分别获取查询及其数据。这会让任何出错的机会 *。将其与您在PHP中执行的任何字符串编码/切片/替换操作相比较,最后您仍然会向数据库发送一个长字符串。你将不得不考虑每一个。可能。组合。 可能逃脱的角色(没有双关语意)你的消毒工作。您还必须了解MySQL理解的每个可能的转义序列组合,这可能会导致意外结果。你已经逃过了',太棒了。我将如何插入\作为字符串中的最后一个字符?然后您的查询将是:

INSERT INTO foo VALUES ('bar"\')

糟糕。**

mic drop

* 你当然可以用任何方式射击自己,但至少在逃避方面,它是可靠的。

** 如果您无法查看此查询的问题,请参阅以下评论。

答案 1 :(得分:1)

htmlspecialchars()str_replace("'",'',$_GET['id'])做同样的方式保护您。它们都以不按“原样”保存数据的方式改变原始数据。更重要的是,由于它们不是这项工作的预期功能,相同的编码,字符集(或其他因素,我不知道)可能会打败“保护”。如果您不想使用准备好的语句,正确的函数是mysqli_real_escape_string(或类似的OOP)(请注意名称上的“i”)也注意到,即使这个函数需要注意字符集。两个附注:对于预期的整数,它足以停止注入:$value = (int)$_GET['id'],以防止使用XSS注入htmlspecialchars