原始 SQL
当您编写 SQL 时——对于任何真正需要人工输入的东西,已经做了很多事情来避免注入。
听说过 SQL 注入的每个人都知道(我将使用 PHP 作为示例)做这样的事情是不安全的:
$sql = "SELECT * FROM `users`
. WHERE `userName` = "{$_POST["username"]}"
. AND `pass` = "{$_POST["pass"]}";";
魔法
然后,当然,有人提出了使用“魔术转义引号”来处理由于不良做法而没有正确清理并直接放入 sql 的程序输入的想法。这并没有真正解决 SQL 注入的问题,但它确实意味着所有用户输入都被破坏了。
添加斜杠
因此,有些人关闭了魔术引号。然后,他们在 SQL 之前解析用户输入addslashes()
,理论上通过 SQL 转义所有引号,而您的黑客无法做到这一点' OR 1=1
,但即使是 addlashes 的文档,它自己也说您不应该使用 addlashes,它说使用数据库-等具体功能mysql_real_escape_string()
,但有些人仍然认为这还不够。
添加特定于数据库的斜线
所以,我们不能使用特定于 DBMS 的*_real_escape_string
,我们不能使用add slashes
,“魔术引号”的东西引起了很多问题,而且网络上到处都是简短的引号,例如:
“一个专门的黑客会找到一种方法来跳过你的引号转义循环,只需使用 DBAL 准备好的语句” - John Q 任何程序员
好的,这让我害怕到使用准备语句和 DBAL。它并没有真正解释什么,但听起来不错,因为我听过很多次。
准备好的报表
所以现在我们正在使用 PDO,或者来自框架的 DBAL,或者其他包装我们所有 sql 并确保有人无法运行 sql 注入的东西。
我的问题基本上是“为什么不?”,而不是“我应该使用什么?”。网络上到处都是告诉你使用这个或使用那个或其他的人,但没有解释为什么这些事情必须发生。
直接问题
有针对性的问题(提醒一下,我问的是 SQL,PHP 是一种示例语言,因为它在 SQL 方面的表现不佳,概念是通用的):
- 为什么我们不能使用“魔术”转义所有用户输入?
- 为什么addlashes“不够好”?
- 使用特定于 DB 的转义函数有什么问题,为什么它比 addlashes 更好?
- 为什么带有框架和 PDO 的预处理语句被誉为 SQL 的黄金标准?为什么他们更好?为什么我不能使用这些进行 SQL 注入,而我可以使用前面提到的方法呢?程序员不能以某种方式仍然搞砸吗?他们应该注意什么?
- 还有什么我没有提出来的担忧吗?