Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disable CSRF token on login form

I am using Symfony2.0 and FOSUserBundle, and would like to disable the csrf token on my login form.

I have disabled the csrf protection globally on my website in my config.yml:

framework:
    csrf_protection:
        enabled:        false

This is working well, there is no csrf field added to my forms. However, this does not apply to the login form. On this form only, I get an "Invalid CSRF Token" error if I don't include the token in the form with:

<input type="hidden" name="_csrf_token" value="{{ csrf_token }}" />

How can I disable the CSRF token on the login form?

like image 307
fkoessler Avatar asked Mar 07 '13 11:03

fkoessler


People also ask

How do I disable CSRF?

You can disable CSRF protection by setting the csrf. protection. enabled system configuration item to the value false. This can be done via REST API.

Do you need CSRF token on login?

Yes. In general, you need to secure your login forms from CSRF attacks just as any other. Otherwise your site is vulnerable to a sort of "trusted domain phishing" attack. In short, a CSRF-vulnerable login page enables an attacker to share a user account with the victim.

Can we bypass CSRF token?

Using the Attacker's Anti-CSRF Token: When the server only checks if a token is valid but does not check which user the token is associated with, an attacker can simply provide their own CSRF token to satisfy server's check and bypass the CSRF protection.

Does every form need CSRF token?

No, you just need to generate a token on a per-session basis.


3 Answers

You can disable CSRF protection in your form class by setting 'csrf_protection' => false in its options array:

class LoginType extends AbstractType
{
    // ...

    public function getDefaultOptions(array $options)
    {
        return array(
            'data_class'      => 'Acme\UserBundle\Entity\User',
            'csrf_protection' => false
        );
    }

    // ...

} 

In case you are using FormBuilder to create your form instead of an AbstractType class, you can pass the options array as the second parameter for createFormBuilder() like this:

$form = $this->createFormBuilder($users, array('csrf_protection' => false))
        ->add( ... )
        ->getForm();
like image 147
Juan Sosa Avatar answered Oct 16 '22 18:10

Juan Sosa


If you just go to your security.yml file and remove the csrf_provider from the form_login directive, don't need to update the action class or anything.

like image 19
Daum Avatar answered Oct 16 '22 20:10

Daum


if you're using FOSUserBundle, and you would like to disable CSRF protection only on the login form, there are a few steps to follow.

Step 1) Create your own user bundle & Security Controller file

In order to over-ride the SecurityController that is built into FOSUserBundle, you must first create your own user bundle.

So, create a file called app/src/{YourApp}/UserBundle/Controller/SecurityController.php You should extend the original SecurityController class, and copy over the loginAction method

use FOS\UserBundle\Controller\SecurityController as SecurityControllerOrig;
class SecurityController extends SecurityControllerOrig
{
   public function loginAction(Request $request)
   {
   }
}

Within the loginAction method, comment out, or remove these lines:

$csrfToken = $this->container->has('form.csrf_provider')
        ? $this->container->get('form.csrf_provider')->generateCsrfToken('authenticate')
        : null;

Then make sure that nothing is passed to view for the CSRF token:

return $this->renderLogin(array(
        'last_username' => $lastUsername,
        'error'         => $error,
        'csrf_token' => false,
    ));

Step 2) Disable CSRF checking in Symfony's firewall (security.yml)

Make sure you comment out the existing "csrf_provider:" line in security.yml:

firewalls:
        main:
            pattern: ^/
            form_login:
                provider: fos_userbundle
                #csrf_provider: form.csrf_provider

Step 3) Override the routing for FOSUserBundle's security controller (routing.yml)

In routing.yml, comment out these lines:

fos_user_security:
    resource: "@FOSUserBundle/Resources/config/routing/security.xml"
    options:
        expose: true

Add these lines below the commented-out lines:

#Over-ride the SecurityController of the FOSUserBundle:
fos_user_security_login:
  path: /login
  defaults:  { _controller: YourAppUserBundle:Security:login }
  methods:  [GET]
  options:
    expose: true

fos_user_security_check:
  path: /login_check
  defaults:  { _controller: FOSUserBundle:Security:check }
  methods:  [POST]
  options:
    expose: true

fos_user_security_logout:
  path: /logout
  defaults:  { _controller: FOSUserBundle:Security:logout }
  methods:  [GET]
  options:
    expose: true

Note 1: I've only asked it to use the loginAction method from your custom SecurityController. The other two methods go to the parent class (not sure if it makes a difference).

Note 2: You need the "expose: true" part! Otherwise, you'll get a JavaScript error from the fos js routing bundle.

That should do it!

like image 1
Jay Sheth Avatar answered Oct 16 '22 19:10

Jay Sheth