zf2 csrf无法正常工作

时间:2016-01-20 13:25:50

标签: php zend-framework2 csrf csrf-protection zend-validate

我们可以轻松打破ZF2的CSRF。如果我们在连字符(-)之后删除字符串,则CsrfValidator不会出现任何错误并且令牌已成功提交。

例如编辑令牌token = 245454547kck-kjhjh2454dh后的CSRF token = 245454547kck- ZF2成功提交表单,但必须提供错误。

任何人都可以检查这个并告诉我是否有解决此问题的方法。

对于上述情况,我们使用:

$csrfValidator = new CsrfValidator(array(
    'name'=> 'token_name',//(here i used 'csrf' also)
    'salt'=> 'test_salt',
));
$csrf = new CsrfElement('token_name');
$csrf->setCsrfValidator($csrfValidator);
$this->add($csrf);
$this->csrf = $csrf;

验证者:

$inputFilter->add(
    $factory->createInput(array(
        'name'     => 'token_name',
        'required' => true,
        'validators' => array(
            $this->csrf->getCsrfValidator()
        )
    ))
);

请提供解决方案。

1 个答案:

答案 0 :(得分:0)

据我所知,这是预期的行为,以保持向后兼容性。

字符串的第二部分是用于在同一会话中跟踪多个反CSRF令牌的令牌ID(不是实际的反CSRF令牌)。如果在验证期间没有设置ID(如在您的示例中),则代码仅检查会话存储中的哈希。源代码表明这是为了避免BC中断(see source code

如果你真的想强制执行令牌ID,你可以扩展Zend\Validator\Csrf并覆盖getValidationToken()(即删除BC代码):

class MyCustomCsrf extends \Zend\Validator\Csrf
{
    /**
     * Get validation token
     *
     * Retrieve token from session, if it exists.
     *
     * @override
     * @param string $tokenId
     * @return null|string
     */
    protected function getValidationToken($tokenId = null)
    {
        $session = $this->getSession();
        if ($tokenId && isset($session->tokenList[$tokenId])) {
            return $this->formatHash($session->tokenList[$tokenId], $tokenId);
        }
        return;
    }
}