Henrik Bjrnskov

Hello there! I am a developer with a big crush on open source. I work for Peytz & Co in Copenhagen, Denmark.

You can see of my open source projects on GitHub (Stampie, Bernard etc.) and read my ramblings on Twitter.

Symfony2: Add Cross Site Request Forgery protection to login forms

29 Dec 2011

When talking with @jmikola on #Symfony-dev this afternoon we got into the subject of cross site request forgery and symfony2 login forms. And it seems that form-login already supports this but neither of us knew how it worked. So here is another quick tip. This time about securing you login form from cross site attacks.

To add it to your login form it is needed to add csrf_provider key about what provider you want to use. For this we can use the default one that the Form component uses. Also we can add a csrf_parameter key but theres a default with the value of _csrf_token.

Here is a full example of the config file:

# app/config/security.yml
security:
    firewalls:
        default:
            pattern: ^/
            form_login:
                login_path: session_new
                check_path: session_new
                csrf_provider: form.csrf_provider

Obviously now when you submit a login form it wont work because they token is not getting printed out. So lets fix that with a couple of lines of code.

First the controller action. The string sent to the generateCsrfToken method is used for generation. It is the "intention" and authentication is the default for form login.

<?php

class SecurityController
{
    public function loginAction()
    {
        // Here goes all the normal stuff like getting the last username and error
        // so we are playing $username and $error is already set.

        $csrfToken = $this->container->get('form.csrf_provider')->generateCsrfToken('authentication');

        return $this->container->renderResponse('MyBundle:Security:login.html.twig', array(
            'username' => $username,
            'error' => $error,
            'csrf_token' => $csrfToken,
        ));
    }
}

Last but not least the template