3

Currently I try to use the CSRF Protection of the Zend Framework 2.

But everytime I send my form, I got this error message:

The form submitted did not originate from the expected site

I have implemeted the CSRF Protection in this way:

1) created a Form Class and added the csrf:

$this->add(array(
    'type' => 'Zend\Form\Element\Csrf',
    'name' => 'secret',
    'options' => array(
        'csrf_options' => array(
            'timeout' => 600
        )
    )
));

2) echoed the csrf element in the view file:

 echo $this->form()->openTag($forgotPasswordForm);
 echo $this->formRow($forgotPasswordForm->get('email'));
 echo $this->formRow($forgotPasswordForm->get('secret'));
 echo $this->formSubmit($forgotPasswordForm->get('submit'));
 echo $this->form()->closeTag($forgotPasswordForm);

I figured out that the csrf token isn't stored in the session, but why?

raina77ow
  • 103,633
  • 15
  • 192
  • 229
  • Just to make sure, did you test another browser? I've had some issues in the past where the browser was the only issue. – Sam Apr 30 '13 at 18:18
  • Tested in Firefox and Chrome, both the same. The `isValid()` method of the form return `false`. –  May 01 '13 at 09:48
  • can you def confirm that the csrf element is being output to the browser, actually look at the HTML it is producing? – mic May 01 '13 at 19:06
  • Yes there is a hash value named "secret" at the browser output. On each request, the Zend Framework seems to regenerate a csrf token, because it doesn't find one in the session. Than the token of the request is invalid. Have I to start a session, or to configure a session? Haven't done anything in this way. –  May 02 '13 at 05:59

3 Answers3

2

I had this line in my Controller:

$forgotPasswordForm = new ForgotPassword();
$forgotPasswordForm->prepare();

I moved $forgotPasswordForm->prepare() to the view file and now it works :-)

Thank you for your support!

1

You can instantiate the form in the controller, or inject with DI, but $form->prepare() must be done y the view. Almost use a hidden in the view for de csrf.

I use this cheatsheet, it´s the best i found for ZF2, it almost has things for doctrine 2. http://zf2cheatsheet.com/#controller

Here´s the code i use.

<?php
// module/Album/src/Album/Form/AlbumForm.php:
namespace Album\Form;

use Zend\Form\Form;
use Zend\Form\Element;

class AlbumForm extends Form
{

    public function __construct($name = null)
    {

        parent::__construct('album');
        $this->add(array(
            'name' => 'id',
            'type' => 'Hidden',
        ));
        /* not including other elements for short answer*/
        **$this->add(new Element\Csrf('security'));**

        $this->add(array(
            'name' => 'submit',
        'type' => 'Submit',
        'attributes' => array(
            'value' => 'Go',
            'id' => 'submitbutton',
            ),
        ));
    }

}

<?php
// module/Album/view/album/album/add.phtml:
$form->setAttribute('action', $this->url('album', array(
        'action' => 'add' )));
**$form->prepare();**

echo $this->form()->openTag($form);
echo $this->formHidden($form->get('id'));
echo $this->formRow($form->get('title'));
echo $this->formRow($form->get('artist'));
**echo $this->formHidden($form->get('security'));**
echo $this->formSubmit($form->get('submit'));
echo $this->form()->closeTag();
ElSniffer
  • 11
  • 2
0

i just use the csrf/element in the form and use the csrf/validator in my input validators. the csrf/validator must be constructed with same name as element

gerard
  • 179
  • 5