【问题标题】:PHP Session Security TipsPHP 会话安全提示
【发布时间】:2011-06-09 10:12:55
【问题描述】:

这就是我目前正在做的在登录页面上创建会话。

if($count==1) {

   $_SESSION['username'] = $username;
   $_SESSION['password'] = $password;
}

我知道这是非常基本的,我需要保护用户会话。你能给我一些基本的提示吗?如果您可以编辑代码并编写安全代码,那就太好了。谢谢。

目前,我使用电子邮件地址作为会话用户名。

【问题讨论】:

  • 那你为什么将密码以纯文本形式存储在 /tmp 中?

标签: php security session


【解决方案1】:

问你自己这个问题:

  • 当用户名在数据库中唯一时,我为什么要存储密码

在你回答了你应该得出的结论之后,它没有意义,你可以在登录系统时将用户名或用户 ID 存储在会话中。

登录系统的工作原理是用户将用户名密码从表单发送到对其进行验证的服务器,在验证过程中,您从数据库where username = post_username 中选择用户。

如果没有找到用户不存在的行,那么您可以直接发送输出,如果用户确实存在,则将密码与 post_password 进行比较。

我们专门通过用户名选择行的原因是您应该结合某种散列系统来增加额外的安全性。

如果您将密码存储为 (password + hash) 这将是一个新字符串,您也将只存储哈希,因此如果找到用户,那么您可以从 (post_password + db_hash) 创建一个哈希并查看如果它与db_password 相同。

这样,如果您的数据库以某种方式泄露,您的用户凭据会更安全。

一旦用户得到验证,您将在会话中存储用户 ID,然后在每次页面加载时,您可以检查该 ID 是否在会话中,以及用户当前是否已登录,您可以选择用户数据来自SELECT * FROM users WHERE id = session_id

这应该让你开始。

【讨论】:

    【解决方案2】:
    /*
        SecureSession class
        Written by Vagharshak Tozalakyan <vagh@armdex.com>
        Released under GNU Public License
    */
    
    class SecureSession {
        // Include browser name in fingerprint?
        var $check_browser = true;
        // How many numbers from IP use in fingerprint?
        var $check_ip_blocks = 0;
        // Control word - any word you want.
        var $secure_word = 'random_string_here';
        // Regenerate session ID to prevent fixation attacks?
        var $regenerate_id = true;
    
        // Call this when init session.
        function Open()
        {
            $_SESSION['ss_fprint'] = $this->_Fingerprint();
            $this->_RegenerateId();
        }
    
        // Call this to check session.
        function Check()
        {
            $this->_RegenerateId();
            return (isset($_SESSION['ss_fprint'])
    
            && $_SESSION['ss_fprint'] == $this->_Fingerprint());
        }
    
        function Destroy()
        {
            // Unset all of the session variables.
            $_SESSION = array();
    
            // If it's desired to kill the session, also delete the session cookie.
            // Note: This will destroy the session, and not just the session data!
            if (isset($_COOKIE[session_name()])) {
                setcookie(session_name(), '', time()-42000, '/');
            }
    
            // Finally, destroy the session.
            session_destroy();
        }
    
    
        // Internal function. Returns MD5 from fingerprint.
        function _Fingerprint()
        {
            $fingerprint = $this->secure_word;
            if ($this->check_browser)
                $fingerprint .= $_SERVER['HTTP_USER_AGENT'];
    
            if ($this->check_ip_blocks)
            {
                $num_blocks = abs(intval($this->check_ip_blocks));
    
                if ($num_blocks > 4)
                    $num_blocks = 4;
    
                $blocks = explode('.', $_SERVER['REMOTE_ADDR']);
    
                for ($i=0; $i<$num_blocks; $i++)
                {
                    $fingerprint .= $blocks[$i] . '.';
                }
            }
            return md5($fingerprint);
        }
    
        // Internal function. Regenerates session ID if possible.
        function _RegenerateId()
        {
            if ($this->regenerate_id && function_exists('session_regenerate_id'))
                session_regenerate_id();
    
        }
    }
    

    【讨论】:

    • 用于创建、检查和销毁安全会话的手动 gnu 类。
    • 如果我想设置注销时间,那该怎么做呢?就像我的网站用户管理员应该在 15 分钟不活动后注销,如何在这个类中设置这个注销时间?
    【解决方案3】:

    通常的做法是根据数据库检查用户名和密码,然后在成功时仅将用户 ID 存储在会话中。稍后,要查看某人是否已登录或授权,请检查存储在会话中的用户 ID。但是,会话变量只对服务器可见,除非您做错了什么。所以它并不可怕或不安全,但它基本上是不必要的。

    编辑

    删除了一些关于 cookie 的内容,可能会引起混淆。

    【讨论】:

    • 为什么我不能简单地存储用户名而不是 id?我没有使用 cookie。
    • @sarthak:因为通过主键而不是一组其他列查询表通常更好更快。如果您使用此会话进行身份验证,则意味着您也在使用 cookie,否则没有意义。
    • 你可以,但我不会,除非它是你的主键,而且你通常想要一个 INT 类型的主键。
    • @jweyrich,用户名是唯一的,它可以是主要的,它类似于基于整数的 id 的因素。您没有正当理由将 id 存储在用户名上,因为它们都具有相同的属性 bar string vs int,事实上,通过使用 id 和用户名,您使用更多的存储空间,因为您的数据库中有一个额外的列,没有真正的很好的理由。
    • @profitphp:将用户 ID 直接存储在 cookie 上会招致假冒攻击和可能的权限提升。请注意,用户可以更改 cookie 上的 ID,从而以其他人的帐户登录。
    猜你喜欢
    • 2012-07-22
    • 1970-01-01
    • 1970-01-01
    • 2011-11-06
    • 2020-04-16
    • 2011-02-11
    • 2012-12-29
    相关资源
    最近更新 更多