I have a page that contains 3 forms, each one with a Zend_Form_Element_Hash for CSRF protection.
The problem is that 2 of them work well with the CSRF but, the other one have problems with the Hash.
The first time I submit it, it returns the “missingToken” error. After that, if I try to submit it again, it works fine….
I made a var_dump($_SESSION) to see what was going on and the output was:
In the View (when the form is created):
array(7) {
...
["__ZF"]=>
array(3) {
["Zend_Form_Element_Hash_routeSearch_csrf"]=>
array(2) {
...
}
["Zend_Form_Element_Hash_registration_csrf"]=>
array(2) {
...
}
["Zend_Form_Element_Hash_login_csrf"]=>
array(2) {
...
}
}
["Zend_Form_Element_Hash_routeSearch_csrf"]=>
array(1) {
["hash"]=>
string(32) "2e348e982e5d8849a7bcb3f42fdd6c0d"
}
["Zend_Form_Element_Hash_registration_csrf"]=>
array(1) {
["hash"]=>
string(32) "6fd74223bb158cc3cc780ee29b26ae58"
}
["Zend_Form_Element_Hash_login_csrf"]=>
array(1) {
["hash"]=>
string(32) "d07dc1ac514082f1960c300670414399"
}
}
After submit:
array(6) {
...
["__ZF"]=>
array(2) {
["Zend_Form_Element_Hash_login_csrf"]=>
array(2) {
...
}
["Zend_Form_Element_Hash_routeSearch_csrf"]=>
array(2) {
...
}
}
["Zend_Form_Element_Hash_login_csrf"]=>
array(1) {
["hash"]=>
string(32) "d07dc1ac514082f1960c300670414399"
}
["Zend_Form_Element_Hash_routeSearch_csrf"]=>
array(1) {
["hash"]=>
string(32) "b9378bec2fd18cf232f451ed602acf0a"
}
}
As you see, “Zend_Form_Element_Hash_registration_csrf” has disappeared…
I tried everything I know but didn’t found what could make the session to disappear… Any ideas? What in Zend could cause that?
By the way, 2 of the forms are loaded by the same Controller in different Actions (one of them is the form with problems). Could it be the reason why the session disappears?
Please, help because I don’t know anymore what to do to find the problem… I’m stuck here =S.
—— EDIT ——
Ok, I found what is causing this… The problem is that the form have Ajax requests and, when they occur, the CSRF Hash expires (Hop=1).
Anyone knows a solution to use a form with CSRF + AJAX calls?
Ok, I solved this adding the CSRF element in the Action that shows the form and in the Action that validates it before saving to the Database, instead of creating it on my Form Class
To prevent the repetition of code, I created this class:
Then, in the Action that shows the form and in the other Action where it’s validated, I use this code: