【问题标题】:How to CSRF secure a form that posts to another page?CSRF 如何保护发布到另一个页面的表单?
【发布时间】:2011-10-29 19:38:51
【问题描述】:

我有一点关于 CSRF 安全性和登录表单的问题。表单的工作方式如下:

在主布局中,视图助手会创建一个登录表单,并且稍后还会在用户通过身份验证时显示用户特定的菜单。

    // User menu viewhelper
public function authentication()
{
    // Check if user is authenticated or not
    $auth = Zend_Auth::getInstance();

    if(!$auth->hasIdentity())
    {
        $form = new Application_Form_Login();
        $form->setAction($this->_view->url(array('action' => 'login'), 'ucp', true));

        return $form;
    }
    else
    {
        // return user specific menu
    }
}

表单发布到包含所有用户控制面板逻辑的 UcpController,例如登录/注销和显示用户特定信息。

    // loginAction in UcpController
public function loginAction()
{
    if(Zend_Auth::getInstance()->hasIdentity())
    {
        $this->_redirect('/');
        return;
    }

    $request = $this->getRequest();

    $form = new Application_Form_Login();

    if($request->isPost())
    {
        if($form->isValid($post = $request->getPost()))
        {
            // Do authentication stuff here.
        }
    }

    $this->view->form = $form;
}

遗憾的是,CSRF 令牌无法匹配,我不知道如何解决这个问题。我在这里错过了什么吗?我应该一起删除 CSRF 验证吗?

// The CSRF protection element as added to the login form
$this->addElement('hash', 'csrf',
    array(
        'ignore' => true
    )
);

在此先感谢,非常感谢您的帮助:)

【问题讨论】:

    标签: php forms zend-framework csrf


    【解决方案1】:

    您的代码似乎正确,我认为问题可能出在其他地方。要调试此问题,请执行以下操作:

    使用 firebug 检查生成的Application_Form_Login,尤其是 CSRF 令牌,然后当您发布数据时,尝试将数据发送到您的 loginAction 中的Zend_Debug::dump $_SESSION$_POST 数组并比较结果。您应该在发布的数据和会话数据之间找到匹配项。

    您应该在发送的帖子变量和名为Zend_Form_Element_Hash_salt_<name-of-your-element> 的会话变量之间搜索匹配项,如果值匹配,则错误在其他地方,您应该转储$form->getMessages() 以找到它。

    正如 zerkms 在评论中指出的那样,我之前的句子是错误的。我查看了implementation,发现 ZF 中的 CSRF 令牌每 300 秒更改一次,在您的情况下,令牌过期应该不是问题。

    【讨论】:

    • 每个请求的新 CSRF 令牌真的很痛苦。每个会话的令牌就足够了,并且与每个 http-request 实现一样安全。
    • @zerkms 我错了,在 ZF 中,令牌每 300 秒更改一次(默认情况下)我刚刚更新了答案。谢谢。
    • 这有点奇怪,会话数据显示一个空数组。
    • 我还发现来自视图助手的“小”登录表单的令牌与正在验证的表单对象不同。
    【解决方案2】:

    问题解决了!我遇到了遇到同样问题的人。原因很奇怪:http://tinyurl.com/3fkg8bk(ZF 论坛)。

    当它转向我时,我的网站图标正在返回 HTTP 500 代码,因为该文件不存在。这显然会触发一个新的 CSRF 生成。我不知道为什么,但它解决了我创建图标并将其上传到 webroot 的问题。

    感谢您至少与我一起思考!

    【讨论】:

    • 太好了,当我发布小表单并且凭据不正确时,我遇到了一个问题,加载大表单会导致页面上加载 2 个相同的表单。提交大表单时,令牌无法再次验证。
    猜你喜欢
    • 1970-01-01
    • 2015-05-05
    • 2012-08-19
    • 2012-06-24
    • 2015-04-18
    • 1970-01-01
    • 1970-01-01
    • 2013-09-30
    • 1970-01-01
    相关资源
    最近更新 更多