Zend Framework Form Hash Ajax
This one sucked hunting down the answer.
The problem. I would include a token (hash) in the form I was producing. I set the form as a checkbox that as soon as it's checked it fires off an AJAX request with the token, and data. The first time it worked great, every other time it would tell me the Token was missing. Hmmmm....
http://codeutopia.net/blog/2008/10/16/how-to-csrf-protect-all-your-forms...
Hi Jani, I got a work around for the problem. The real problem is this, for AJAX requests, it works for first time and not for the subsequent requests. The AJAX request was having the same token for all it’s requests but the plugin was generating unique token for all the requests. So is the mismatch / problem. That was the problem.
Workaround:
What I did was, for each AJAX request, I stopped generating a new token and used the already generated one to compare. So by this way I can cover for multiple AJAX requests. It could be vulnerable for the time that it lives and after that I will eject (logout) the user from the system and then they (attacker) will have to login again and get a token and then attack (if they wanted to really). That was it.
I never did find an answer yet, I did post it to StackOverFlow
http://stackoverflow.com/questions/2474774/how-to-use-zend-framework-for...
Instead I did the whole thing manually..
Form
class Form_GroupListForm extends Zend_Form
{
public function __construct($options = null)
{
parent::__construct($options);
$this->setName('grouplist');
$groupmodel = new Default_Model_Group();
$groups = new Zend_Form_Element_MultiCheckbox('groups');
$groups->addMultiOptions($groupmodel->getGroupList())
->setLabel('Groups')
->setDescription('Groups this person belongs to:')
->setAttrib('class', 'ajaxcheckbox')
;
$token = new Zend_Form_Element_Hash('grouplisttoken');
$token->setSalt('hello')
->setTimeout(3600) // Form times out after one hour
->removeDecorator('HtmlTag')
->removeDecorator('Label');
$myNamespace = new Zend_Session_Namespace('authtoken');
$myNamespace->authtoken = $hash = md5(time());
$auth = new Zend_Form_Element_Hidden('authtoken');
$auth->setValue($hash)
->setRequired('true')
->removeDecorator('HtmlTag')
->removeDecorator('Label');
$this->addElements(array($groups, $auth));
}
}
Notice the session being generated then stored as a hidden field. Dumb that I have to basically replicate the hash feature, but the hash has an hop of 1, meaning that it can only be used for one page refresh then it expires. There should be a way to persist this token over several ajax calls.