2011-08-18 45 views
0

我有一个关于CSRF安全性和登录表单的问题。该表单的工作原理如下:如何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 
    ) 
); 

谢谢你的帮助是极大的赞赏:)

回答

0

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

随着它转向我,我的图标正在返回HTTP 500代码,因为该文件不存在。这显然触发了一个新的CSRF产生。我没有丝毫的线索,但它解决了我创建图标并将其上传到webroot的问题。

谢谢至少和我一起思考!

+0

伟大的现在我遇到了一个问题,当我张贴小表单和凭据不正确,大表单加载导致2相同的形式加载在页面上。当我提交大型表单时,令牌无法再次验证。 –

0

您的代码似乎是正确的,我想这个问题可能是别的地方。要调试这个问题,这样做:当你发布数据

使用Firebug检查生成Application_Form_Login,尤其是CSRF令牌,然后尝试Zend_Debug::dump$_SESSION$_POST阵列在你的LoginAction和比较的结果。您应该在发布的数据和会话数据之间找到匹配。

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

正如zerkms在评论中指出的,我之前的这句话是错误的。我查看了implementation,并且我看到ZF中的CSRF令牌在300秒内发生了一次更改,此超时过期令牌不应成为您的问题。

+2

每个请求的新CSRF令牌非常痛苦。每个会话的令牌数量足够,并且按照每个http请求实现的安全性。 – zerkms

+0

@zerkms我错了,在ZF中令牌在300秒内改变一次(默认情况下)我刚刚更新了答案。谢谢。 – Fabio

+0

这很好奇,会话数据显示一个空数组。 –