2
votes

I have this login form via Symfony2 security documentation with the following TWIG template content:

<form action="{{ path('login_check') }}" method="post">
    <div class="input form">
      <label for="username">Account name or E-mail:</label>
      <input type="text" id="username" name="_username" value="{{ last_username }}" required="required" />
    </div>
    <div class="input form">
      <label for="password">Password:</label>
      <input type="password" id="password" name="_password" required="required" />
    </div>
    <input type="hidden" name="_token" value="{{ csrf_token("intention") }}">
    <button type="submit">Log In</button>
</form>

And I want to add CSRF protection in this form. As you can see, I added this line <input type="hidden" name="_token" value="{{ csrf_token("intention") }}"> but I'm not really sure, if it is enough to activate this protection.

My controller has same form as on the doc, so it looks like this:

<?php
// src/Acme/SecurityBundle/Controller/SecurityController.php;
namespace Acme\SecurityBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Security\Core\SecurityContext;

class SecurityController extends Controller
{
    public function loginAction()
    {
        $request = $this->getRequest();
        $session = $request->getSession();

        // get the login error if there is one
        if ($request->attributes->has(SecurityContext::AUTHENTICATION_ERROR)) {
            $error = $request->attributes->get(
                SecurityContext::AUTHENTICATION_ERROR
            );
        } else {
            $error = $session->get(SecurityContext::AUTHENTICATION_ERROR);
            $session->remove(SecurityContext::AUTHENTICATION_ERROR);
        }

        return $this->render(
            'AcmeSecurityBundle:Security:login.html.twig',
            array(
                // last username entered by the user
                'last_username' => $session->get(SecurityContext::LAST_USERNAME),
                'error'         => $error,
            )
        );
    }
}

So it's enough just paste one hidden input with value {{ csrf_token("intention") }} or I have to add something into controller?

2

2 Answers

2
votes

I found that Answer from @Chris McKinnel isn't true. Now, the Symfony2 has on the tutorial page this section:

http://symfony.com/doc/current/cookbook/security/csrf_in_login_form.html

I need add line in my security.yml:

    form_login:
        # ...
        csrf_provider: form.csrf_provider

And change this

<input type="hidden" name="_token" value="{{ csrf_token("intention") }}">

to

<input type="hidden" name="_csrf_token" value="{{ csrf_token("authenticate") }}">

Now I am sure my authentication form si CSRF protected.

1
votes

CSRF protection is enabled by default, so all you need to do is render your CSRF token in your HTML. You don't need to do anything in your controller.

You have a couple of options:

  1. Do it just like you've done it above
  2. Use {{ form_rest(form) }}, this will render all fields that you haven't rendered yet, including hidden fields like the CSRF token

Either will work fine.