【发布时间】:2014-04-29 08:42:02
【问题描述】:
我昨晚在阅读有关防止 SQL 注入的内容,我遇到了这个答案:
How can I prevent SQL injection in PHP?
“你的常识”中的 cmets 听起来像是功能失调/不安全。然而,在我的(尽管有限的)测试中,我发现 php 的“bin2hex($var)”适用于我扔给它的任何东西——文字数字、数字字符串、文本字符串——即使在匹配数字 (tinyint) 列时也是如此。
我的问题是:当每个用户输入都通过十六进制进行清理时,有没有办法注入 SQL?从本质上讲,任何时候进行查询时,它都会看起来像这样:
$query="SELECT * FROM table WHERE someidentifier=UNHEX('".bin2hex($unsafe_user_input)."') LIMIT 1"
基本上翻译成:
SELECT * FROM table WHERE someidentifier=UNHEX('0b99f') LIMIT 1
这种类型的安全性是否存在漏洞?
PS - 我不只是在寻找诸如“为什么不将 PDO 或 MySQLi 与准备好的语句一起使用?”之类的答案?它可能属于抢先优化的巨大弊端,但我宁愿不要将我的查询开销加倍(是的,我明白使用多个相同的查询可以更快,但这不是我经常遇到的情况)。
【问题讨论】:
-
不要推出自己的消毒功能。这很可能是安全的,但是当您可以使用标准的“保证安全”版本时,为什么还要发明自己的“可能安全”系统?
-
在 PDO 和/或 MySQLi(最好是后者)中是否有不涉及双倍给定查询开销的清理方法?我在 w3schools 上阅读了一些关于过滤器的信息,但我知道它们不是一个非常值得信赖的来源......
-
您可以通过手动转义来滚动您自己的查询,例如
real_escape_string。准备查询的开销是真实的,但在宏伟的计划中它是非常小的。只是不要犯在插入循环内准备查询的错误。准备工作应该做一个。然后,您只需多次执行该准备好的语句。 -
请记住那些说“不要编写自己的查询,使用 pdo/mysqli+prepared 语句”来防止 sql 注入攻击的人似乎从未意识到您仍然可以编写完全可注入的查询不无论您使用的是什么数据库库。他们是工具。如果你锯断了你的腿,那不是电锯的错。 PDO/mysqli 可以帮助编写安全查询,但不能让您编写安全查询。
-
非常好的注意事项,感谢您指出这些。您能想出一种可以将其注入的方法吗?
标签: php mysql sql sql-injection sanitize