3

I'm using both sfDoctrineGuard and sfForkedDoctrineApply. I've written a module that permits a logged-in user to create a child-user which inherits a few of the parent's profile settings. It works great, the way it is written, however I have to turn off csrf protection for the whole app (in settings) in order to get it working because when it is turned on, it (rightfully, I might add) detects a csrf attack. So, I need a way to turn it off, or at least catch and remove the validation.

I've tried many techniques, none of which have worked. Including:

      $this->disableLocalCSRFProtection(); 

in the form. Problem is, it's a custom form and the parent config is being called which is injecting the csrf protection.

I've read a few solutions that I think are pointing in the right direction: Symfony 1.4: Custom error message for CSRF in forms but they don't address this specific problem.

Suggestions and solutions are welcome. Thanks in advance.

Community
  • 1
  • 1
Patrick
  • 315
  • 1
  • 8
  • 27
  • Where are you making the `$this->disableLocalCSRFProtection();` call? In `YourForm::configure()`? – Mike Purcell Feb 29 '12 at 21:26
  • Yes, I made that call in my form config. – Patrick Feb 29 '12 at 21:46
  • "_it's a custom form and the parent config is being called which is injecting the csrf protection_" Do you have a possibility to disable csrf protection in the parent form using `disableLocalCSRFProtection()`? – melekes Mar 01 '12 at 15:36
  • I can, but then it would turn it off for all subsequent form calls (the parent forms) in which it is needed. To do so, I would have to disable it in the base form class. But that just gave me an idea. I might be able to add a variable to the base form class and pass the disable command in for circumstances which need it. I'll tinker around with that and let you know if it works. – Patrick Mar 01 '12 at 16:01

2 Answers2

7

The base sfForm constructor configures whether enabled and what will be the CSRFSecret.

class sfForm implements ArrayAccess, Iterator, Countable
{
  public function __construct($defaults = array(), $options = array(), $CSRFSecret = null)
  {
    $this->setDefaults($defaults);
    $this->options = $options;
    $this->localCSRFSecret = $CSRFSecret;

    $this->validatorSchema = new sfValidatorSchema();
    $this->widgetSchema    = new sfWidgetFormSchema();
    $this->errorSchema     = new sfValidatorErrorSchema($this->validatorSchema);

    $this->setup();
    $this->configure();

    $this->addCSRFProtection($this->localCSRFSecret);
    $this->resetFormFields();
  }
}

In such cases, where disabling local CSRF protection via disableLocalCSRFProtection() doesn't work, you may try to create the form instance with a "false" CSRFSecret".

Example:

$myForm = new myForm(array(), array(), false);

Edit: (The above suggestion didn't work for the poster)

Could you please try, just commenting the "csrf_secret" configuration in your application's settings.yml. After commenting this line, don't forget to clear symfony's cache. To verify that CSRF protection is disabled globally, you may check the value of the "sf_csrf_secret" configuration as follows;

var_dump(sfConfig::get('sf_csrf_secret'))

This should give you a boolean false, which implies in deed all CSRF protection is disabled.

Wilq
  • 2,245
  • 4
  • 33
  • 37
Lashae
  • 1,372
  • 1
  • 20
  • 36
  • Yeah, I should have mentioned that I had tried that solution too... to no avail. Any other idea? I think, and I could be way off base here, that the problem is that two csrf tokens are being submitted (one for the logged in user, and one that is being created for the new user)... which is why it is correctly detecting a csrf attack when csrf is enabled. – Patrick Feb 29 '12 at 21:45
  • Patrick, I hope my latest edit works for you. I'm adding "this" comment to have timeline in the question, ie. when edit is done. – Lashae Feb 29 '12 at 22:01
  • Sorry for the delay... life got in the way. I did as you suggested, and I did indeed get a bool(false) on the echo of the success page. So, my question becomes why am I still getting a "csrf_token required" msg when I turn on csrf protection? It baffles me. – Patrick Mar 01 '12 at 15:49
  • I think we havent fixed the question. From the main question what I understand is "you need to completely disable CSRF protection for your application" if it is so; removing the "sf_csrf_secret" directive completely from the settings.yml will be sufficient. However, you say "why am I still getting a "csrf_token required" msg when I turn on csrf protection". Then, let me ask why are you turning on the CSRF protection? – Lashae Mar 02 '12 at 12:00
6

$this->disableLocalCSRFProtection(); didn't work for me either. I succeeded by setting the crsf validator required option to false right after create the form.

<?php
    $form = new UploadImageForm();
    $form->getValidator($form->getCSRFFieldName())->setOption('required', false);

    if ($request->isMethod(sfWebRequest::POST)) {
        ...
?>
Firula
  • 1,251
  • 10
  • 29
  • Worked like a champ. Need this for a rest implementation, where CSRF is unneeded, rather api key authentication is used. – Mike Purcell May 18 '16 at 20:45