Как я могу защитить пользователей от подделки межсайтовых запросов с помощью Zend Framework? - PullRequest
1 голос
/ 26 октября 2009

Моя программа использует Zend Framework, и я хотел защитить пользователей от CSRF с помощью Zend_Form_Element_Hash. Но, похоже, это не работает.

Например, мой код для формы выхода из системы

    $exithash = new Zend_Form_Element_Hash('hihacker', array('salt' => 'exitsalt'));
    $this->addElement($exithash);

В моем плагине Auth для контроллера я делаю

    $exitForm = new R00_Form_Exit();

    if ($exitForm->isValid($_POST)) {
        R00_Auth::logout(); // a wrapper for Zend_Auth::getInstance()->clearIdentity();

        Zend_Registry::get('Log')->info('User has logged out');

        $this->setRedirect($request); // redirect to the current page
    }

И в моем макете

    echo new R00_Form_Exit();

Хорошо. Но это не работает, я нажимаю кнопку отправки формы, страница перезагружается, но идентичность все еще существует.

Как я понял, Zend_Form_Element_Hash генерирует новое значение хеша для каждого времени, когда форма создает и сравнивает хеш от пользователя с хешем из сеанса - последний сгенерированный хеш! Это очень странно Даже если я попытаюсь, например, создать только один R00_Form_Exit в моем приложении, сохранить его в реестре и вывести его из него, открытие страницы с моего сайта «в новой вкладке» приведет к тому, что все такие формы, защищенные csrf, перестанут работать. 1014 *

Итак, как мне защитить?

Ответы [ 3 ]

1 голос
/ 07 ноября 2009

Предполагается, что каждый раз, когда вы вызываете генератор хеша, он будет отличаться в указанном вами пространстве имен SESSION. Вот почему вы создаете хэш только тогда, когда создаете реальную форму. При этом сохраняется хэш для одного прыжка (что означает загрузку страницы), а затем он забывается (особенно), если вы перегенерируете форму для пользователя. Это цель CSRF! Чтобы предотвратить угон формы путем аннулирования устаревших форм. (в основном)

Если вы не можете «проверить» форму из-за того, что хеш-код меняется каждый раз, вы выполняете задачу в неправильном порядке и вам необходимо пересмотреть процесс.

1 голос
/ 26 октября 2009

Вы должны проверить, может ли Zend_Form_Element_Hash сохранить хэш в пространстве Zend_Session_Namespace. Это ожидаемое поведение в соответствии с документацией этого элемента: Zend Documentation

0 голосов
/ 26 октября 2009

Здесь я предлагаю свое собственное решение. Но это все еще не очень круто, поэтому я буду рад услышать любые другие, лучшие решения и комментарии об этом.

Я генерирую хеш для каждого пользователя из его хеша пароля и других параметров. Хеш является постоянным для каждого пользователя, пока он не изменит свой пароль:

   public function getSecurityHash() {
          return md5( $this->getIntID() . $this->getLogin() . 'R00SuperSalt' );
   }

А, в виде:

    $exithash = new Zend_Form_Element_Hidden('exithash');
    $exithash->setValue( R00_Auth::getUser()->getSecurityHash() )
             ->addValidator('Identical', false, array(
                R00_Auth::getUser()->getSecurityHash()
              ))
             ->setDecorators(array('ViewHelper'))
             ->setRequired(true);
...