PHP 会话安全提示

问题描述 投票:0回答:3

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

if($count==1) {

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

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

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

php security session
3个回答
6
投票

问自己这个问题:

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

在您回答完之后,您应该得出这样的结论:它毫无意义,您可以在登录系统时将用户名或用户 ID 存储在会话中。

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

where username = post_username

如果没有发现任何行,则用户不存在,因此您可以在此时直接发送输出,如果用户确实存在,则将密码与

post_password
进行比较。

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

如果您将密码存储为(密码+哈希),这将是一个新字符串,您也将只存储哈希。因此,如果找到用户,那么您可以从

(post_password + db_hash)
创建一个哈希并检查它是否与
db_password
相同。

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

用户经过验证后,您将在会话中存储用户 ID,然后在每个页面加载时,您可以检查 ID 是否在会话中,以及用户当前是否已登录,您可以选择用户数据由

SELECT * FROM users WHERE id = session_id

这应该可以帮助您开始。


1
投票
/*
    SecureSession class
    Written by Vagharshak Tozalakyan <[email protected]>
    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();

    }
}

1
投票

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

编辑

删除了一些有关 cookies 的内容,可能会引起混乱。

© www.soinside.com 2019 - 2024. All rights reserved.