Search code examples
phpformssymfony1csrf

Symfony CSRF Attack Detected even when passing _csrf_token


Here is my form:

<form novalidate action="<?php echo url_for('article/submit') ?>" method="POST">
  <?php echo $form['title']->renderRow() ?>
  <?php echo $form['content']->renderRow() ?>
  <?php echo $form->renderHiddenFields() ?>
  <input type="submit" value="Save"/>
</form>

And looking at the generated HTML source, the _csrf_token IS in fact being rendered. Here is my action:

public function executeSubmit(sfWebRequest $request)
{
  $this->forward404Unless($request->isMethod('post'));
  $request->checkCSRFProtection();

  die('submitting post...');
}

The error:

_csrf_token [CSRF attack detected.]

Even in my action if I do a var_dump($_POST); die; I get:

Array
(
  [title] => string(8) "My title"
  [content] => string(10) "My Content"
  [_csrf_token] => string(32) "<my token here>"
)

So the csrf token is definitely being rendered and passed correctly. What am I doing wrong?

Also, is there any documentation for checkCSRFProtection() anywhere? The API doc's dont' say anything about it besides acknowledging it's existence.


Solution

  • A few things to check:

    (Source: From http://oldforum.symfony-project.org/index.php/t/17867/)

    Be sure you have defined your "secret" in your settings:

    csrf_secret: ThisIsMySecret  # Unique secret to enable CSRF protection or false to disable`
    

    Also, based on what I've gathered from that form post, CSRF protection checking is done automatically in $this->form->isValid(), so your call to $request->checkCSRFProtection() is unnecessary if you are already checking if the form is valid. If not, add $this->form->isValid().

    It would also seem that $request->checkCSRFProtection() doesn't work with forms; it's purpose (if I'm correct) is to validate requests served when a user clicks a link. When CSRF protection is enabled, link_to() automatically adds CSRF protection to the links it generates. So, basically, the CSRF protection for a form is different for that of a request that didn't originate from a form.

    See this ticket for more details: http://trac.symfony-project.org/ticket/7315

    Another ticket that may be of interest: http://trac.symfony-project.org/ticket/5698