【问题标题】:PHP form token usage and handlingPHP表单令牌的使用和处理
【发布时间】:2011-01-03 07:20:41
【问题描述】:

我是一名使用 PHP 编写登录脚本的初学者。这是我到目前为止的表单令牌声明:

$_SESSION["form_token"] = md5(rand(time (), true)) ;

该语句在用户表示他/她要登录后立即发出。

我有限的理解是token的目的是在唯一的时间点识别唯一的用户,并伪装表单token的信息。

然后一切都变得模糊。以下是我的 3 个未解决问题:

  1. 出于安全目的“检查”表单令牌的最佳时间是什么时候?

  2. 如何检查?

  3. 如果有的话,我什么时候“销毁”表单令牌? (IOW,表单令牌会在用户注销之前保持“活动”吗?

【问题讨论】:

  • 仅供参考 MD5 有点受限,如果您需要生成随机字符串,我建议您改用它:$id = sha1(mt_rand());如果你使用 rand(),你只会得到 32,000 种可能的组合。

标签: php forms login token


【解决方案1】:

您可以查看 zend 框架实现。

除了具体的实现,文档还描述了这种元素在表单上的推理和使用。

它的 Zend_Form_Element_Hash https://docs.zendframework.com/zend-form/element/csrf/

【讨论】:

    【解决方案2】:

    没有必要做你正在尝试的事情。当您在 PHP 中使用 session_start() 启动会话时,已经为您生成了一个唯一的 SESSIONID。您应该将其放在表单上。默认情况下通过 cookie 处理。也不需要检查 SESSIONID,它再次为您处理。

    您负责对用户进行身份验证并存储他们经过身份验证的身份(例如,SESSION 中的 $_SESSION['user_id'] = $userId。如果用户注销,您将使用 session_destroy 销毁他们的会话。

    您应该确保 session_start() 是您网站中所有页面的首要项之一。

    这是一个基本的例子:

    <?php
    session_start(); // starts new or resumes existing session
    session_regenerate_id(true); // regenerates SESSIONID to prevent hijacking
    
    function login($username, $password)
    {
        $user = new User();
        if ($user->login($username, $password)) {
            $_SESSION['user_id'] = $user->getId();
            return true;
        }
        return false;
    }
    
    function logout()
    {
        session_destroy();
    }
    
    function isLoggedIn()
    {
        return isset($_SESSION['user_id']);
    }
    
    function generateFormHash($salt)
    {
        $hash = md5(mt_rand(1,1000000) . $salt);
        $_SESSION['csrf_hash'] = $hash
        return $hash;
    }
    
    function isValidFormHash($hash)
    {
        return $_SESSION['csrf_hash'] === $hash;
    }
    

    编辑:我误解了原来的问题。我在上面添加了用于生成和验证表单哈希的相关方法;

    请参阅以下资源:

    【讨论】:

    • 有些东西我不明白。我也将 php 会话用于令牌,但每次我修改一个会话时,它们都会被修改(所有 tmp 文件的“修改日期”都会更改)。识别不同用户的会话之间是否存在联系?
    【解决方案3】:

    这是为了防止 CSRF 攻击

    http://en.wikipedia.org/wiki/Cross-site_request_forgery

    理论上,恶意网站可能会显示一个发布到您的应用程序的表单。该表单可能包含导致数据泄露或某些不需要的操作的说明。用户可能会被欺骗提交应用程序将接受的表单,因为用户已经登录。表单令牌确保表单是由您的站点而不是其他站点创建的。

    检查 HTTP_REFERER 通常足够好,但不是完整的解决方案(例如,https 不会发送引荐来源网址字符串)。

    如果您真的想使用令牌保护所有表单,您可以创建一些方便的函数,例如 emitToken() 和 checkToken(),使其在站点范围内工作。

    一些例子:

    http://phpsec.org/projects/guide/2.html

    http://www.rodsdot.com/php/CSRF_Form_Protection.php

    【讨论】:

    • HTTP_REFERER 不可信,永远不要依赖它,因为它很容易被编辑!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-26
    • 1970-01-01
    • 2013-01-03
    • 1970-01-01
    • 2012-07-26
    • 2014-06-19
    • 1970-01-01
    相关资源
    最近更新 更多