在另一个问题中有评论说明如下:
“说到数据库查询, 总是尝试使用准备好的 参数化查询。 mysqli和 PDO库支持这一点。这是 比使用转义更安全 功能如 mysql_real_escape_string“。
所以,我想问的是:为什么准备参数化查询更安全?
答案 0 :(得分:47)
我认为这里缺少的一个重要观点是,对于支持参数化查询的数据库,没有“逃避”需要担心。数据库引擎不会将绑定变量组合到SQL语句中,然后解析整个事物;绑定变量保持独立,永远不会被解析为通用SQL语句。
这就是安全和速度的来源。数据库引擎知道占位符仅包含数据,因此永远不会将其解析为完整的SQL语句。当您准备一次声明然后多次执行时,加速就会到来;规范示例是将多个记录插入同一个表中。在这种情况下,数据库引擎只需要解析,优化等一次。
现在,有一个问题是数据库抽象库。他们有时通过将绑定的变量插入到具有正确转义的SQL语句中来伪造它。不过,这比自己做的好。
答案 1 :(得分:7)
首先,你将把危险字符的转义留给数据库,这比人类更安全。
...它不会忘记逃避,或错过任何可用于注入恶意SQL的特殊字符。更不用说,你可能会提升性能!
答案 2 :(得分:5)
我并不是非常精通安全,但这是一个解释,我希望能帮到你:
假设你有一个如下声明:
从mydb
中选择[整数]假装准备它时,语句在我们想象的sql实现中被编译为字节。
01 00 00 23
Opcode for select Prepared bytes number of "mydb"
for your integer
现在执行时,您将把数字插入为预备语句保留的空间。
比较它如果你只是使用转义,你可能会在那里插入尽可能多的乱码并可能导致内存溢出,或者一些bizzare sql命令他们忘了逃避。
答案 3 :(得分:2)
因为有了准备好的陈述,你不能忘记逃避内容。所以没有办法引入不安全感。
mysql_real_escape_string和准备好的语句一样安全如果你每次调用mysql_query时都记得使用mysql_real_escape_string,但很容易忘记。
答案 4 :(得分:1)
由于此漏洞http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string,该函数不安全。这就是为什么准备好的陈述是首选的,它也可以提高性能。
答案 5 :(得分:1)
准备好的语句解决了fundamental problem of application security仅仅数据卫生不会:它们导致完全分离数据和指令。当两人感到困惑时,就会产生不安全感。这适用于SQL注入以及缓冲区溢出。
(还有其他不安全的方法。)
答案 6 :(得分:0)
非常好的情况,可能不是,但它至少同样安全;为什么要冒这个机会?