【发布时间】:2012-06-28 07:56:45
【问题描述】:
我已经对准备好的语句有了基本的了解,并且我知道它们可以防止 SQL 注入攻击。但我还没有理解为什么他们可以防止上述攻击。我知道有人问过类似的问题,但我没有找到完全令人满意的答案。
示例 - 非常不安全的代码
所以这里我们有了与数据库通信的最基本方式:
$query = "SELECT * FROM users where id=$username";
在没有任何保护的情况下,用户可以输入恶意代码,从而“欺骗”数据库引擎执行破坏性查询:
$username = "1; DROP TABLE users;"
SELECT * FROM users where id=1; DROP TABLE users;
我不明白准备好的语句如何设法“过滤掉”此类数据。它背后的机制是什么不会诱使数据库生成如上所示的 SQL 查询?是像转义某些字符一样简单,例如上例中的分号,还是更复杂?
如果我要像示例中那样进行精确的注入攻击,但通过准备好的语句运行它,什么样的命令字符串会到达数据库引擎?
【问题讨论】:
-
简而言之:真正的预准备语句是数据库服务器不可或缺的一部分:从来没有“完整查询”,只有预准备语句,然后告诉数据库你要使用什么变量。这样,查询的意图就不会被误解。
-
安全优势只是一个副产品。准备好的语句用于没有字符串插值的语言,但主要用于优化执行计划。只有当您严格遵守它们时,安全方面才会发挥作用。他们只是删除了繁琐的手动和容易出错的转义部分。你仍然应该了解上下文,否则你以后会被它绊倒。
标签: php mysql sql-injection