【问题标题】:Are Numbers As Validated Password Reset Is It Safe?数字作为验证密码重置是否安全?
【发布时间】:2017-11-05 01:27:01
【问题描述】:

我有一张如下表:

|-------|-----------|-------------------|---------------|-----------|
|   id  |   name    |       email       |   password    |   code    |
|_______|___________|___________________|_______________|___________|
|       |           |                   |               |           |
|   1   |   user1   |   user1@gmail.com |   PASSWORD    |   8989    |
|_______|___________|___________________|_______________|___________|
|       |           |                   |               |           |
|   2   |   user2   |   user2@gmail.com |   PASSWORD    |   7676    |
|_______|___________|___________________|_______________|___________|

如您所见,我随机填充了一列code。为什么该列存在,目的是什么? 最初,我在创建密码重置页面时遇到了麻烦,然后我创建了一个唯一的 code 作为每个用户的验证。

注册

<?php
include_once 'MySQLiConnect.php';

if(isset($_POST['signup'])) {

    $username = $Connection->real_escape_string($_POST['username']);
    $email = $Connection->real_escape_string($_POST['email']);
    $password = $Connection->real_escape_string($_POST['password']);
    $code = (rand(1111,9999));
    $hashed_pwd = password_hash($password, PASSWORD_DEFAULT);

    $query = "INSERT INTO users(name,email,password,code) VALUES('$username','$email','$hashed_pwd','$code')";

        if ($Connection->query($query)) {
            echo "Success";
            }
}
$Connection->close();
?>

<html>
<body>

<form method="post">
    <input type='text' name='username'/>
    <input type='email' name='email'/>
    <input type='password' name='password'/>
    <button type='submit' name='signup'>Register</button>
</form>

</body>
</html>

用户输入数据并注册后,随机生成code。假设code是8989。用户不会知道code,只有在请求重置密码后才知道。

如果用户忘记了密码,那么用户可以通过在之前通过电子邮件收到的字段字段中输入code 来重置密码。

重置密码

<?php
include_once 'MySQLiConnect.php';
    $inputmail = $Connection->real_escape_string($_POST['email']);
    $inputcode = $Connection->real_escape_string($_POST['code']);
    $newcode = (rand(1111,9999));
    $newpass = $Connection->real_escape_string($_POST['password']);
    $hashed_pwd = password_hash($newpass, PASSWORD_DEFAULT);

if(isset($_POST['savepass'])) {

    $check_email = $Connection->query("SELECT * FROM users WHERE email='".$inputmail."'");
    $user_check = $check_email->fetch_array();

if ($inputcode == $user_check['code']) {
    $query = "UPDATE users SET password='".$hashed_pwd."', code='".$newcode."' WHERE email='".$inputmail."'";

        if ($Connection->query($query)) {
            echo "Password updated";
        }
    } else {
        echo "Code wrong!";
    }
}
$Connection->close();
?>

<html>
<body>

<form method="post">
    <input type='email' name='email'/>
    <input type='text' name='code'/>
    <input type='password' name='password'/>
    <button type='submit' name='savepass'> Update </button>
</form>

</body>
</html>

上面的代码我删减了很多,我只做了重要的部分。抱歉,如果可能有问题。但对于原版,工作没有问题。

但是我为什么要提出这个问题呢? 我需要你对这个技巧的意见,因为我不太确定code 是否安全或可能被黑客入侵。因为code是用纯文本写的,没有加密。

等待您的建议。谢谢。

【问题讨论】:

  • 四位数的代码很短。使用适当的 hash,从用户对象的某些属性加上随机值生成 - 至少 sha1。另外,您应该实施一种机制,使代码在合理的时间后过期(“行业标准”可能是 24 小时。)每次用户请求密码重置时创建一个新的哈希值;不是以前。添加尝试请求代码的计数器;并在很长一段时间内阻止用户帐户这样做,如果这种情况经常发生的话。

标签: php database passwords


【解决方案1】:

不,不是。

如果有人(以某种方式)从您的站点获得数据库转储,他们可以使用纯文本存储代码使用每个帐户登录。此外,您很容易受到任何使用此角度攻击您的人的攻击:他们只需要使用每个电子邮件组合测试数字 1000-9999。也没有任何代码可以保护自己免受此类大规模登录尝试。

Jeff Atwood 最近在博客中提到了hash security。如果您担心您的用户密码保护,请阅读它:)

如果这是一个面向公众的网站,我建议允许您的用户使用他们的 Facebook、Github、Google 等帐户登录 - 以适合您的目标受众的为准。这样,您根本不必实施密码重置。让那些公司担心如何为您安全地执行此操作...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-28
    • 2014-04-29
    • 1970-01-01
    • 1970-01-01
    • 2013-09-18
    • 2019-08-30
    • 2019-10-20
    • 2019-07-02
    相关资源
    最近更新 更多