Мы можем легко сломать CSRF ZF2. Если мы удалим строку после дефиса (-
) CsrfValidator
не выдает никакой ошибки и токен успешно отправлен.
Например CSRF token = 245454547kck-kjhjh2454dh
после редактирования токена 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()
)
))
);
Пожалуйста, предоставьте решение.
Насколько я могу судить по коду, это ожидаемое поведение для обеспечения обратной совместимости.
Вторая часть строки — это идентификатор токена (не фактический токен анти-CSRF), используемый для отслеживания нескольких токенов анти-CSRF в одном сеансе. Если во время проверки не установлен идентификатор (как в вашем примере), код просто проверяет хэш в хранилище сеансов. Исходный код указывает, что это было сделано во избежание разрыва BC (см. исходный код)
Если вы действительно хотите применить идентификатор токена, вы можете расширить 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;
}
}
Других решений пока нет …