Php 准备好的SQL语句与转换为GET变量的htmlspecialchars有什么不同?

Php 准备好的SQL语句与转换为GET变量的htmlspecialchars有什么不同?,php,security,mysqli,sql-injection,Php,Security,Mysqli,Sql Injection,所以我在我的网站上乱搞SQL注入,试图找到一种简单的方法来保护它不受SQL注入的影响。我发现了很多关于“准备好的SQL语句”的东西,主要是在 这一切都很好,是的,它确实阻止了我所知道的任何类型的SQL注入,也阻止了所有用于测试安全性的应用程序进行SQL注入 然而,我发现所有注入都是一样的,那就是使用“引号”。我的问题是:当我可以简单地阻止使用htmlspecialchars运行查询时,为什么要使用准备好的语句或类似的东西 例如: $id = htmlspecialchars($_GET['id'

所以我在我的网站上乱搞SQL注入,试图找到一种简单的方法来保护它不受SQL注入的影响。我发现了很多关于“准备好的SQL语句”的东西,主要是在

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

然而,我发现所有注入都是一样的,那就是使用“引号”。我的问题是:当我可以简单地阻止使用htmlspecialchars运行查询时,为什么要使用准备好的语句或类似的东西

例如:

$id = htmlspecialchars($_GET['id'], ENT_QUOTES);
$query = Mysqli_Query($dbc, "SELECT * FROM `Users` WHERE `user_id`='$id'") or die(mysql_error());
这通过将字符改为'阻止了所有注入,这在MYSQL语句中是无效的


我是不是遗漏了什么?人们使用预先准备好的语句有什么原因吗?

好的
htmlspecialchars()
保护您的方式与此
str\u replace(“”,“,$”GET['id')保护您的方式相同。
do。它们都以一种不“按原样”保存数据的方式修改原始数据。更重要的是,由于它们不是这项工作的预期功能,相同的编码、字符集(或其他因素,我不知道)可能会破坏“保护”。如果您不想使用prepared Stations,则正确的函数是(或类似于OOP)(请注意名称上的“i”)也请注意,即使此函数也需要注意字符集。两个注意事项:对于预期的整数,停止注入就足够了:
$value=(int)$\u GET['id']
,为了防止XSS注入,使用htmlspecialchars

参数化查询是一种数据库功能;数据库本身提供了一个API来分别获取查询及其数据。这使得出现任何问题的可能性为零。将其与在PHP中执行的任何字符串编码/切片/替换操作进行比较,最终仍然会向数据库发送一个长字符串。你必须考虑每一件事。可能的结合体这些角色可能会逃脱(没有双关语)你的净化努力。您还必须知道MySQL能够理解的所有可能的转义序列组合,这可能会导致意外的结果。你逃过了
,太好了。我将插入一个
\
作为字符串中的最后一个字符,怎么样?那么您的查询将是:

INSERT INTO foo VALUES ('bar"\')
哎呀**

麦克风下降

*当然,你仍然可以用多种方式射击自己的脚,但至少在逃跑方面,这是可靠的


**如果您看不到此查询的问题,请参阅下面的评论。

good read我们每隔两周就会收到一个问题,询问“为什么我应该使用准备好的语句”,答案仍然是一样的:这是一种经过验证的机制,应该在任何可用的地方使用。尝试“做得更好”总是不容易(参数化无论如何都很容易),而且您可能会错过一个安全问题。在任何情况下,
htmlspecialchars()
都不是SQL的正确转义函数-如果您不使用绑定变量,您至少应该使用数据库库提供的转义函数。如果A、B、C和D可能重复,那么它可能会工作。。。或者,你可以使用一个完全没有“如果”和“但是”的解决方案,并且只起作用。你的选择。是的,对不起,这是一个极端的比较。我的观点是1-保留数据库中的数据,2-向OPI显示正确的函数将查看真实的逃逸字符串,但实际上你没有回答我的问题。我还准备使用int-check,当我希望数字是唯一有效的字符时,但我将尝试寻找一个函数,该函数将检查ID是否只包含UTF-8中有效的明文,这将解决我的问题。为什么我没有回答你的问题?这是因为我没有htmlspecialchars()失败的例子?是的,没错。但请确定,我也不会搜索那个案例。也许有效,但可能失败,因为这不是目的。但无论如何,它都不会按原样保存数据。足够丢弃它。我指给你看一个函数,它直接替换了错误的htmlspecialchars,这将解决任何问题。这就是我的anwser的精神。我投了你一票,但你没有像deceze那样提供例子,所以他的答案是“更好”。仍然感谢您的时间,我向您保证,在这种情况下,我将使用真实的\u escape\u字符串而不是HTMLSpecialChars.:)我也投了你的赞成票,这不是重点(但谢谢),我认为不需要一个例子。这就像在哪里编写htmlspecialchar、编写mysqli\u real\u escape\u string(并在那里阅读字符集)一样简单。这就是我需要的答案。非常感谢。我确实理解参数化查询是如何工作的,我只是好奇其他解决方案,我发现代码结构更简单、更好。我想你真的只是说你觉得mysqli绑定参数的API不令人满意。这是绝对正确的,非常糟糕。试试PDO,它的API要好得多。你可以用现在的两行代码做同样的事情。我还没有读到任何关于PDO的文章,我只是觉得Mysqli更容易理解,所以我正在使用它。我有很多东西要学,我正在努力做到这一点。:)@Luis此查询不会“无任何问题执行”。此特定查询将生成语法错误。(很难区分,但最后一个
是红色的,而它应该是黑色的)。但它实际上应该演示如何通过使字符串引用无效/绕过字符串引用打开另一个可能的注入向量,即使给定的引用是“转义的”。应该说这并不容易,要考虑的事情比你想的要多,你真的能确定你已经考虑了所有事情吗?对不起,我的错,我已经对sqlite进行了测试,你的例子是正确的,它失败了!