我应该mysql_real_escape_string在注册表单中输入的密码吗?


Should I mysql_real_escape_string the password entered in the registration form?

当用户注册I clean密码时,mysql_real_escape_string如下

$password = clean($_POST['password']); 

在将其添加到数据库之前,我使用:

$hashedpassword = sha1('abcdef'.$password);

并保存到mySQL中。

我的问题是我应该清理它,还是我保护密码在添加到DB之前是散列的?

嗯,有一个主要的误解。

mysql_real_escape_string() 清理任何东西。这和安全一点关系都没有

此函数仅用于转义分隔符,仅此而已。它可以帮助您将字符串数据放入SQL查询-仅此而已。

所以,你要放入查询的每个字符串(通过把它放在引号里),你必须用这个函数准备它。在所有其他情况下,它都是无用的,甚至是有害的。

,
出于这种误解,你在这里犯了两个主要错误:

  • 你在使用这个函数而不是用数据去查询
  • 你可以通过添加一些符号来破坏你的密码,所以,它变得不可用

另外,作为一个边注,请记住,这个函数应该始终与mysql_set_charset一起使用,否则这个函数的"_real_"部分变得无用

如果你在它上应用clean()函数(我认为这是一个可怕的混合stripslashes/htmlentities/addslashes),那么你用sha1()生成的哈希可能不是实际密码的哈希。

这将工作意外,即使密码包含特殊字符。但前提是你要一直遵循同样的程序。实际上,您应该在之后正确地转义$sha1散列(即使不需要)。实际上,您应该使用包含更好的盐(每个用户)的方案。

但要回答你的问题:这在你的情况下是有效的;这不是问题。这是不正确的。

是。总是这样。或者,更好的方法是使用占位符(在PDO和mysqli中都可用)来阻止PHP中的SQL注入。

总是使用某种形式的转义(即使是过时且麻烦的mysql_real_escape_string)的原因是为了保持一致。因为"这里不需要它"(因为sha1返回一串十六进制字符而"这里不需要它")而保存几个周期是无关紧要的,如果由于缺乏一致性而导致错误和/或稍后的妥协。

bug/妥协可能是由于缺乏一致性和稍后忘记"转义"不同的字段而引入的,或者可能是由于小代码范围忽略了"转义"的新需求。(想象一下,如果未来的版本保存了二进制base-64 SHA1签名。)这两个微不足道的向量都可以通过更好的实践来消除。

幸福的编码。


用户输入data数据库存储数据。"转义"数据(或者,更好的是,使用占位符/参数化查询)的目的是确保数据正确安全地进入数据库。如果数据需要特殊处理,那么在数据级别处理它——处理SQL的实际操作应该是简单、一致和可靠的。(注意,mysql_real_escape_string不会改变数据库看到的数据,而是确保数据是真实数据——即在数据库解析SQL命令之后传递给mysql_real_escape_string函数的数据。)

这是相当可悲的,但需要"转义"的整个点仍然存在,因为不正确的数据连接到SQL字符串。这个"问题"通过使用占位符已经解决了很多很多年,占位符允许SQL命令和数据保持隔离。准备好的语句也可能更有效,这取决于其他因素。而且,老实说,我不明白人们如何能够忍受看到/编写SQL命令的字符串操作(即使没有所有添加的"转义"代码)所造成的混乱。

没有必要在之后使用哈希传递之外的任何东西,没有任何东西会破坏您的插入,并且XSS将更加不可能。(注意" more impossible "部分)

然而

…我建议您在对密码进行散列之前,先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~
}


现在我可以了,我问,你们为什么要删除邮箱密码恢复的问题?我正准备回答呢

问候。

在这种特殊情况下,如果在查询中只使用字符串的散列形式,则不会受到SQL注入的影响。SHA1不输出任何会破坏字符串的SQL元字符,所以如下:

$pw = sha1($password);
$sql = "INSERT INTO .... VALUES ('$pw')";

将是"安全的"。

然而,养成总是转义所有内容的习惯是一个很好的实践,即使不是严格要求。当它不需要的时候,最好稍微过火一点,而不是忘记它在一个小地方,你的网站被破坏了。

实际上,在这种情况下,这里不需要mysql_real_escape_string,因为sha1只返回a-f0-9字符的字符串,不能转义。

但是在这里跳过它是个坏主意。
为什么如果你将sha1改为其他函数,可能会导致错误。简单地说,您将忘记添加mysql_real_escape_string。此外,它更语义(我甚至没有谈到安全)使用转义函数为您的所有操作:存储在db,打印HTML/XML,执行shell命令。

此外,正如pst所说,使用占位符

是一个好主意