当用户使用mysql_real_escape_string
注册我 clean 密码时,如下所示
$password = clean($_POST['password']);
在将其添加到数据库之前,我使用:
$hashedpassword = sha1('abcdef'.$password);
并将其保存到mySQL中。
我的问题是,在将密码添加到数据库之前,我应该清理密码还是保护密码?
答案 0 :(得分:10)
嗯,有一个主要的误解。
mysql_real_escape_string()不 清理 任何内容。它与安全无关。
此函数仅用于转义分隔符,仅此而已。它可以帮助您将字符串数据放入SQL查询 - 这就是全部。
因此,您要查询的每个字符串(通过将其放在引号中),您必须使用此函数进行准备。在所有其他情况下,它将是无用的甚至是有害的。
因此,
出于这种误解,你在这里犯了两个重大错误:
另外,请注意,请记住此函数应始终与mysql_set_charset一起使用,否则此函数的"_real_"
部分将变得无用
答案 1 :(得分:2)
是。总是。或者,更好的使用占位符(PDO和mysqli中均可用)请参阅best way to stop SQL injection in PHP。
始终使用某种形式的转义(即使是过时且繁琐的mysql_real_escape_string
)的原因是要保持一致。保存几个周期,因为“这里不需要它”(并且“这里不需要它”因为sha1
返回一个十六进制字符串)如果由于缺乏一致性而导致无关紧要以后会出现错误和/或妥协。
错误/妥协可能是由于缺乏一致性而忘记在以后“逃避”不同的字段,或者可能是由于代码范围很小而忽略了“逃避”的新要求。 (想象一下,如果未来的版本保存了二进制或 base-64 SHA1签名。)这些琐碎的向量都可以通过更好的实践来消除。
快乐的编码。
用户输入数据。数据库存储数据。 “转义”数据(或者更好的是,使用占位符/参数化查询)确保数据进入数据库正确,安全。如果需要特别处理数据,那么在数据级别处理 - 处理SQL的实际操作应该是简单,一致和可靠的。 (请注意,mysql_real_escape_string
不会更改数据库看到的数据,而是确保数据是真实数据 - 传递给的数据 mysql_real_escape_string
函数 - 在数据库解析 SQL命令之后。)
很遗憾,但由于数据与SQL字符串的不正确连接,需要“转义”的整个点仍然存在。这个“问题”已经解决了许多年,使用占位符允许SQL命令和数据保持隔离。准备好的陈述也可能更有效,这取决于其他因素。而且,老实说,我看不出人们如何看待/编写通过字符串操作创建的混乱(即使没有所有添加的“转义”代码)的SQL命令。
答案 2 :(得分:2)
如果你在它上面应用clean()
函数(我假设它是striplashes / htmlentities / addslashes的可怕混合),那么用sha1()
生成的哈希可能不是哈希实际密码。
即使密码包含特殊字符,这也会偶然 。但只要你总是遵循完全相同的程序。实际上你应该在之后正确地转义$sha1
哈希(即使不需要)。实际上,你应该使用一个涉及更好盐(每用户)的方案。
但回答你的问题:这适用于你的情况;而不是问题。这不正确。
答案 3 :(得分:0)
在这种特殊情况下,如果您只在查询中使用字符串的散列形式,那么您可以安全地进行SQL注入。 SHA1不输出会破坏您的字符串的任何SQL元字符,所以:
$pw = sha1($password);
$sql = "INSERT INTO .... VALUES ('$pw')";
将是“安全的”。
但是,养成一直逃避一切的习惯是好习惯,即使并非严格要求。当它不需要而不是忘记在一个小小的地方并且你的网站被点燃时,最好有点过分。
答案 4 :(得分:0)
实际上,在这种情况下,您不需要mysql_real_escape_string
,因为sha1只返回a-f0-9
个字符串,不得转义。
但是在这里跳过它是个坏主意
为什么要将sha1更改为其他函数,这可能会导致错误。简单地说,您将忘记添加mysql_real_escape_string
。此外,对于所有操作都使用转义函数更加语义(我甚至不谈安全性):在db中存储,打印HTML / XML,执行shell命令。
此外,由于pst
表示使用占位符的好主意
答案 5 :(得分:0)
除了哈希传递之外,没有必要使用以外的任何东西,没有机会阻止你的插入,而 XSS 将更加不可能。 (注意“更不可能”的部分)
但是......我建议您在对其进行散列之前 trim()密码,这样您就可以确保用户输入了一些内容。另外,在“散列”之前用 strlen()检查修剪过的密码
此代码足以用于密码... $ pass 是已发布的密码。
$pass = trim($pass);
if (strlen($pass) > 5) // it has to be bigger than 5 chars long.
{
$pass = sha1($pass); // or use crypt() as some have suggested.
// pass is ready to be inserted.
}
else
{
// pass is not correct and you should handle this as you want~
}
<小时/> 现在,我可以,我问,为什么要删除电子邮件密码恢复问题?我正打算回答。
问候。