Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Functional testing form with CSRF enabled in Symfony

What is the best way of creating functional tests to test forms with CSRF protection enabled in Symfony?

Currently I have to add the following code before each form submittion:

  $form = new sfGuardFormSignin();
  $token = $form->getCSRFToken();
  $token_name = $form->getCSRFFieldName();

Then I add the $token and $token_name to form parameters like this:

call('/login', 'POST', array (
    'signin' => 
    array (
      'username' => $username,
      'password' => $password,
      $token_name => $token,
    )))

The option suggested in the documentation:

'_with_csrf' => true,

Doesn't work at all.

Is there more simple way to avoid adding token to each form tested manually? Or is there a way to turn off csrf checking when running tests?

The way I've described above is ok when you have to test 1-2 forms but if project contains tens unique forms it becomes a pain.

like image 318
Stepashka Avatar asked Feb 20 '10 10:02

Stepashka


People also ask

What is CSRF protection Symfony?

CSRF protection works by adding a hidden field to your form that contains a value that only you and your user know. This ensures that the user - not some other entity - is submitting the given data.

Where we can implement CSRF token?

For additional safety, the field containing the CSRF token should be placed as early as possible within the HTML document, ideally before any non-hidden input fields and before any locations where user-controllable data is embedded within the HTML.

How do CSRF tokens work?

A CSRF Token is a secret, unique and unpredictable value a server-side application generates in order to protect CSRF vulnerable resources. The tokens are generated and submitted by the server-side application in a subsequent HTTP request made by the client.

How do I close CSRF?

You can Disable CSRF on few routes by editing. $except = [] array. It does not seems to be good practice as by doing this we are removing security feature of Laravel.


1 Answers

Of course, you can't use _with_csrf option if you call directly the url. You must pass from the form page, clicking on the submit button. Like so:

click('signin', array('signin' => array('username' => $username, 'password' => $password), array('_with_csrf' => true)))

The string 'signin' must be adapted to your form. You can also use a more label-independent string, like 'form#myform input[type="submit"]' instead of 'signin', adapting the id of your form.

As already suggested, you can disapble CSRF for login, it's really useful for forms that modifies data.

like image 83
Massimiliano Arione Avatar answered Oct 17 '22 04:10

Massimiliano Arione