We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Don't work CSRF secutiry (dubl submit)

Hello! The question is: upon receiving a request for CSRF verification code the first time is all good, but if you press the button a second time - CSRF does not pass. You have to refresh the page... what to do in this situation? Wants to do using checkToken(), but I'm interested in the option with the validation inside a Form. Tried to use $csrf->clear() does not help. What could be the problem? Phalcon 3.0.0



5.8k
edited Aug '16

CSRF is working if you do so:

<input type="hidden" name="csrf" value="{{ security.getToken() }}">

But still does not work if you do so:

{{ form.render('csrf', ['value': security.getToken()]) }} (the value is not updated)



5.8k

Found the cause: when the transfer of the entity (model) to a form does not work $element->close() on the elements. This is a bug or a feature?

edited Aug '16

use:

use Phalcon\Forms\Element\Hidden;
use Phalcon\Validation\Validator\Identical;

class UserRegisterForm extends Form
{

    public function initialize($entity = null, $options = null)
    {
         //... code ...

         // CSRF
        $csrf = new Hidden('csrf');
        $csrf->addValidator(new Identical([
            'accepted' => $this->security->getSessionToken(),
            'message' => 'CSRF validation failed'
        ]));
        $this->add($csrf);
    }
}

Controler o Micro:

 $params = [];

 $form = new UserRegisterForm();

if ($this->request->isPost()) {

    if ($form->isValid($this->request->getpost()) != false) {

    // ... code ...
        if ($user->save()) {

                 return $this->response->redirect(['for' => 'user.register.success']);

        }
    }
}

// important
$this->view->form = $form;

$this->tag->setTitle("Register");
echo $this->view->render('user/register', $params);

Template:

{{ form.render('csrf', ['value': security.getToken()]) }}


5.8k

It is a bad option. This will reset all the fields that I need

use simple:

<div>{{ hidden_field(security.getTokenKey(), "value": security.getToken()) }}</div>

in controller:

if ($this->security->checkToken()) {
           // code...
}