2

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?

Lkopo
  • 4,798
  • 8
  • 35
  • 60

2 Answers2

2

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.

Lkopo
  • 4,798
  • 8
  • 35
  • 60
  • Do you need to call any of your forms "form_login" ? – Aysennoussi Sep 10 '14 at 13:28
  • @Sekai it's an item in configuration for identify login form. In this item you set options such as route for login action or, as you can see in this answer, for csrf provider too. – Lkopo Sep 10 '14 at 13:36
  • Yeah, I agree but I tried to manipulate the token in the form (I added random chars) and submitted my form, and it succeeded. How does the protection work ? – Aysennoussi Sep 10 '14 at 13:38
  • Via FireBug, I change the value of the generated token, to test if my form will succeed or not. sadly the login succeeded even if I changed the crsf token manually. which means that the protection is not set, i think ? – Aysennoussi Sep 10 '14 at 13:40
  • But yeah in your first comment you talked about setting the route for login action, where do I set it ? is it necessary? – Aysennoussi Sep 10 '14 at 13:42
  • Could you post your configuration and template code of your login form? For your second comment, there are official docs for that http://symfony.com/doc/current/book/security.html – Lkopo Sep 10 '14 at 13:43
  • here ^^ http://stackoverflow.com/questions/25767218/how-does-symfony2-crsf-protection-work – Aysennoussi Sep 10 '14 at 13:51
1

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.

Chris McKinnel
  • 14,694
  • 6
  • 64
  • 67