Symfony 1.4: Custom Error Message for CSRF on Forms

Can someone tell me where / how to configure the CSRF token error message for forms in Symfony 1.4. I use sfDoctrineGuard to log in and in this form, especially when every time the session ends and you still have a page, it causes a very unfriendly user error: โ€œCSRF attack detectedโ€. Something like "This session has expired. Please return to the home page and try again." Sounds better.

What is the correct way to do this in a form class?

Thanks.

+7
forms symfony1 csrf sfguard
source share
6 answers

The only way is to overwrite sfForm::addCSRFProtection() .

In /lib/form/BaseForm.class.php you can add this code snippet:

 class BaseForm extends sfFormSymfony { public function addCSRFProtection($secret = null) { parent::addCSRFProtection($secret); if (array_key_exists(self::$CSRFFieldName, $this->getValidatorSchema())) { $this->getValidator(self::$CSRFFieldName)->setMessage('csrf_attack', 'This session has expired. Please return to the home page and try again.'); } } } 

After calling the parent method, you will get the validator associated with the CSRF field and change the message for the csrf_attack code.

Edit: You also need to check if the validator exists. Some forms may disable CSRF protection!

Hope this helps!

+5
source share

None of these answers explain how to remove the โ€œCSRF token:โ€ label, which prefixes the error message in an inactive way (for example, changing the token name is a bad idea!).

The only audible way to remove a tag is to extend the CSRF authentication to cause a global error. While we are doing this, we can also change the error message.

 class myValidatorCSRFToken extends sfValidatorCSRFToken { protected function configure($options = array(), $messages = array()) { parent::configure($options, $messages); $this->addMessage('csrf_attack', 'Your session has expired. Please return to the home page and try again.'); } protected function doClean($value) { try { return parent::doClean($value); } catch (sfValidatorError $e) { throw new sfValidatorErrorSchema($this, array($e)); } } } 

Now, so that our forms use this validator by overriding sfForm::addCSRFProtection in BaseForm :

 public function addCSRFProtection($secret = null) { parent::addCSRFProtection($secret); if (isset($this->validatorSchema[self::$CSRFFieldName])) //addCSRFProtection doesn't always add a validator { $this->validatorSchema[self::$CSRFFieldName] = new myValidatorCSRFToken(array( 'token' => $this->validatorSchema[self::$CSRFFieldName]->getOption('token') )); } } 
+3
source share

In 1.4.4, I had to modify the naag code as ...

 public function addCSRFProtection($secret = null) { parent::addCSRFProtection($secret); if (isset($this->validatorSchema[self::$CSRFFieldName])) { $this->validatorSchema[self::$CSRFFieldName]->setMessage('csrf_attack', 'This session has expired. Please refresh and try again.'); } } 

This made it work, but the csrf token: bit still appears in the error message.

+2
source share

Improving the previous answers, here is the code I'm using:

 public function addCSRFProtection($secret = null) { parent::addCSRFProtection($secret); if (isset($this->validatorSchema[self::$CSRFFieldName])) { $this->validatorSchema[self::$CSRFFieldName]->setMessage('csrf_attack', 'This session has expired. Please refresh and try again.'); $this->getWidgetSchema()->getFormFormatter()->setNamedErrorRowFormatInARow(" <li>%error%</li>\n"); } } 

The default value for NamedErrorRowFormatInARow "<li>%name%: %error%</li>\n" adds a name and a colon. Be careful because it changes the meaning for all forms and all global errors.

You can also change the field by creating your own formatter and using it in the forms you want. You can see the documentation here for more information about this.

+2
source share

Use event dispatcher. Check it out http://bluehorn.co.nz/2010/07/15/how-to-change-csrf-attack-message-in-symfony-1-2/

I wrote it for Symfony 1.2, but using the event dispatcher, so it can still work for Symfony 1.4.

+1
source share

I assume that the csrf token: prefix can be removed or configured by setting the CSRF token field label, of course, of course.

+1
source share

All Articles