在此代码中
UPDATE table SET field = MD5('{$_POST['variable']}') WHERE id = 1;
既然更新后的值是md5'ed,我还应该采取措施防止注入吗?比如addslashes()之类的?
您不是在向SQL查询传递MD5哈希,而是在传递MySQL稍后将进行哈希的纯文本。所以,是的,您应该在这里采取措施来防止SQL注入。或者更好的是,用PHP对其进行散列,然后在查询中使用散列。
如果你正在散列密码,MD5被认为是弱的。请改用bcrypt。
既然更新后的值是md5'ed,我还应该采取措施防止注入吗?
事实上,当代码中的变量进入查询字符串时,并没有经过MD5处理,因此与任何其他变量一样,同样的注入问题仍然适用。
如果您在PHP中完成了$hashedVar = md5($var)
,然后将$hashedVar
添加到查询字符串中,那么您的问题可能会更合理一些,但按照您将MD5()
作为查询字符串本身的一部分进行处理的方式,答案是肯定的,它肯定需要转义以避免注入。
然而,一些额外的注意事项:
-
addslashes()
是而不是将PHP字符串转义为SQL的正确方法。您应该使用适用于您正在使用的DBneneneba API的真正转义字符串函数。如果您使用
mysqli
或PDO
作为DB API,那么您的最佳选择是预处理语句。如果您使用的是较旧的mysql_xxx()
函数,那么您没有此选项,但您应该更新到其他API之一,因为mysql
扩展已弃用。 -
MD5
是而不是密码的安全哈希算法。如果你使用的是纯无盐MD5密码,那么在你开始考虑注入攻击之前,你就已经不安全了。您应该使用更好的哈希算法,如bcrypt。最近的PHP版本包括一组
password_xx()
函数,这些函数是专门为以最小的工作量提供最佳可用质量的哈希而设计的。(这些函数也可通过第三方库用于较旧的PHP版本)。
如果您将一个变量连接到SQL查询中(您应该而不是;您应该使用准备好的语句),那么您需要对其进行转义。
您首先构建一个字符串,然后将该字符串发送到MySQL。MD5()
在查询中并不重要。如果我把'), field2 = 0; -- '
作为$_POST['variable']
发送,你会得到:
UPDATE table SET field = MD5(''), field2 = 0; -- '') WHERE id = 1;
正如你所看到的,这很糟糕。
如果使用PHP加密字符串,那么SQL查询将不会被注入。
$string = md5($_POST['variable']);
$sql = "UPDATE table SET variable = '$string'";
这比使用MySQL的md5
函数要安全得多,但最好养成确保所有用户输入安全的习惯。
正如Spudley所提到的,为了避免SQL注入,应该实现查询转义。MD5确实是一种弱哈希算法(一些脚本儿童工具可以在五分钟内破解它),密码肯定需要用更强大的哈希算法来保护。
话虽如此,我也会考虑到你们系统的威胁和风险环境。如果你正在为一个永远不会连接到互联网的系统开发数据库,唯一的威胁是来自恶意的内部用户或错误(愚蠢的用户风险=非常不可能),MD5可能在短时间内就足够了。如果可以通过互联网或网络连接访问,允许知识渊博的用户故意注入SQL命令,那么您的风险更高,我强烈建议您使用任何比MD5更强的方法。
进一步的缓解措施包括强大的输入验证和通过代理分离数据库Web服务器。如果没有关于你的系统的更多详细信息(请不要在这里发布任何这些细节),我不认为我可以建议任何进一步的防御措施。