real escape string and PDO
我在从MySQL库迁移后使用PDO。我用什么来代替旧的real_escape_string功能?
我需要转义单引号,这样它们就会进入我的数据库,我认为可能有更好的方法来处理这一点,而不添加(斜线)到我的所有字符串。有人能告诉我应该用什么吗?
- 对参与方来说有点晚了,但是如果Prepare()方法不是选项(例如,当您构建自己的模型时),则可以使用pdo::quote()。
你应该使用PDO Prepare
从链接:
Calling PDO::prepare() and PDOStatement::execute() for statements that will be issued multiple times with different parameter values optimizes the performance of your application by allowing the driver to negotiate client and/or server side caching of the query plan and meta information, and helps to prevent SQL injection attacks by eliminating the need to manually quote the parameters.
- 谢谢。我以前读过,但后来听说PDO准备不会阻止SQL注入。我不知道该相信什么了。你确定准备会阻止注射攻击吗?
- PDO防止SQL注入。(它没有帮助防止XSS Vuerabilities,但mysql也没有真正的逃逸)
- 是的,这就是为什么我想要另一个选择。我已经在一些地方读到了这篇文章,并记得我曾经思考过有多少网站现在会受到攻击。我很想自己对此有一个明确的答案。
- 约翰:是的,如果你使用正确,比尔在这篇文章中有一个很好的解释——>stackoverflow.com/questions/1314521/…
- @不,我同意XSS,但我仍然担心准备而不是保护。你确定吗?如果它真的可以防止注入攻击,那么我就用它。
- @子母弹-我有疑问,并没有深入研究,但我认为问别人不会有什么伤害。我可没有下一个乔那么好。
- @斯特德:谢谢,我现在正在看。
- 任何数据库层都无法保护您免受XSS的攻击,因为这是页面输出时间转义的问题,与数据库无关。虽然许多错误引导的作者尝试在SQL转义或输入值溢出的同时进行HTML转义,但这是解决此问题的错误时间,通常会导致不完整的保护以及其他令人讨厌的错误。
- 如果这个答案是正确的,那么为什么我的PDO没有准备好从参数中包含的字符串中正确地转义单引号?
- "PDO PREPARE不会阻止SQL注入"-它将通过常量值(例如变量分配)防止注入,但不会保护其他地方的注入,例如标识符(表/列名称)中的注入。如果使用来自用户输入的表名,那么需要注意避免通过该向量进行SQL注入。
- 有关准备好的语句如何防止SQL注入的深入解释,请阅读:stackoverflow.com/a/12202218。
PDO提供了一种替代方案,旨在用pdo::quote()方法替换mysql_escape_string()。
以下是PHP网站的摘录:
1 2 3 4 5 6 7 8 9 10
| <?php
$conn = new PDO('sqlite:/home/lynn/music.sql3');
/* Simple string */
$string = 'Nice';
print"Unquoted string: $string
";
print"Quoted string:" . $conn->quote($string) ."
";
?> |
上述代码将输出:
1 2
| Unquoted string: Nice
Quoted string: 'Nice' |
- 我目前正在将旧代码迁移到使用PDO的过程中,虽然这个解决方案是一个很好的解决方案,但是人们需要意识到它会在字符串周围加引号。因此,如果人们构建的查询已经有了像"SELECT * FROM users WHERE username = '".$conn->quote($username)."'";这样的引号,那么查询将不可避免地失败。
- 接受的答案可能是推荐的方法和最佳实践,但这个答案是对实际问题的正确答案。有时,您实际上需要使用旧的mysql_escape_string函数,例如,如果您正在构建一个要稍后执行的文件。你不能用事先准备好的声明来做这件事。
使用准备好的语句。它们将数据和语法分开,从而消除了对MySQL数据进行转义的需要。请参见例如本教程。
- 皮斯克沃,谢谢。我已经在使用它们了,只是在错误出现的地方没有。我只是想知道Prepare是否真的能阻止注射攻击。我听过相反的说法,似乎有很多争论。
- @约翰:是的,准备好的语句将停止SQL注入攻击。(当然,SQL注入只是一个可能的攻击向量,因此防止它们不是一个魔法"如果你的网站现在完全安全"的灰尘)
- @约翰没有一场辩论。事实上只有你在辩论。
- 贾维斯:是的。还有……?
- 啊,好吧,只是觉得你还想再加点什么。很好的指向文档的链接,谢谢。
- 准备好的语句并不能抵御所有类型的SQL注入,例如,如果使用动态表名。有关更多详细信息,请参阅我对已接受答案的评论。
- 当然,它们不是万无一失的;只要有足够的努力,你就可以用任何东西射自己的脚。但是,它们确实删除了最常见的错误类型/攻击向量。
- 这在某些情况下是有帮助的,但是如果您试图插入或更新数据,并且列和或表名来自变量,那么就可以了。那就没用了。因为只有当数据在select语句中时,它才会允许您包含列名。因此,如果从变量中获取表名,或者执行插入或更新操作,并且从变量中获取列名,那么仍然需要转义数据。
- @基特拉莫斯:我想说,虽然有各种特殊情况,但准备好的声明对最常见的情况有帮助。当然,如果您正在做一些高级的工作,这可能不是适合该工作的工具;但是我猜90%的SQL语句(以及99.9%的按执行量计算)确实属于选择/插入/更新类别,其中准备好的查询是该工作的正确工具。(从我在代码中看到的内容来看——注意问题来自2010年——动态列名要么是A.高度特定的元代码(数据库管理),要么是B.无体系结构的代码(非规范化))。