PHP MySQLi准备好的绑定参数查询是否安全?
从历史上看,我一直使用PHP MySQLi准备好的绑定参数查询是否安全?
mysql_real_escape_string()
从用户得到的所有输入的是结束了触摸数据库。
既然我已经完全转换为MySQLi,并且我正在使用绑定参数准备的查询,我是否已经有效地消除了SQL注入攻击的可能性?
我是在说我不再需要
mysql_real_escape_string()?
纠正这是我的理解和我的一个项目的基础: http://sourceforge.net/projects/mysqldoneright/files/Base/MysqlDoneRight-0.23.tar.gz/download
这不是我想错了,虽然作为现在我已经发布了它,它也可能会影响其他人。
所有用户提供的输入现在都会在bind_parms中结束。
准备阶段提供的查询是静态的。
这不是那么简单。你可以用它代替插值应用程序变量为SQL表达式来取代文字值仅的绑定参数:
$sql = "SELECT * FROM MyTable WHERE id = ".$_GET["id"]; // not safe
$sql = "SELECT * FROM MyTable WHERE id = ?"; // safe
但是,如果你需要进行动态查询的一部分,除了字面价值?
$sql = "SELECT * FROM MyTable ORDER BY ".$_GET["sortcolumn"]; // not safe
$sql = "SELECT * FROM MyTable ORDER BY ?"; // doesn't work!
该参数将始终被解释为一个值,而不是列标识符。您可以使用ORDER BY 'score'
运行查询,该查询与ORDER BY score
不同,并且使用参数将被解释为前者 - 恒定字符串'score'
,而不是名为score
的列中的值。
因此,在很多情况下,您必须使用动态SQL并在查询中插入应用程序变量以获得所需的结果。在这些情况下,查询参数不能帮助您。您仍然需要保持警惕并进行防御性编码,以防止SQL注入漏洞。
没有框架或数据访问库可以为你做这项工作。您始终可以构建包含SQL注入缺陷的SQL查询字符串,并且在数据访问库看到SQL查询之前执行此操作。那么它应该如何知道什么是故意的和什么是缺陷?
这里有方法来实现安全的SQL查询:
滤波器输入。跟踪插入到SQL查询中的任何变量数据。使用输入filters去除非法字符。例如,如果你期望一个整数,确保输入被限制为一个整数。
退出输出。在此上下文中的输出可以是您发送到数据库服务器的SQL查询。你知道你可以为值使用SQL查询参数,但是列名是什么?你需要一个标识符的转义/引用函数,就像旧的
mysql_real_escape_string()
用于字符串值。代码评论。让别人成为第二双眼睛并浏览你的SQL代码,以帮助你找到你忽略使用上述两种技术的地方。
是的。使用准备好的查询将会跳过参数。
简短,甜美,准确。 – ceejayoz 2009-10-13 17:04:46
谢谢。只是想确保我没有失去明显的东西。我倾向于这样做。 – 2009-10-13 17:14:06
将参数绑定到预处理语句时,会自动转义数据,因此在发送之前不应将其转义。双逃脱通常是一件坏事。至少,它会产生丑陋的结果,并在稍后出现额外的逃脱字符。
是的。注意到你不能执行ORDER BY?位参数。好答案。 – 2009-10-13 22:17:06
我得到了一个downvote? Downvoter,你应该描述你为什么认为这个答案不令人满意。也许我可以改进它。 – 2015-02-16 07:20:31