2 Methods to Check CSRF Tokens in Symfony 8

2 Methods to Check CSRF Tokens in Symfony 8

In a Symfony application, protection against cross-site request forgery (CSRF) attacks is essential when handling form submissions. While the Symfony Forms component includes CSRF protection automatically, there are situations where you work with plain HTML forms and need to handle tokens yourself. This tutorial provides 2 methods for how to check CSRF tokens in a Symfony 8 application.

Below is a simple HTML form that manually includes a CSRF token generated in the Twig template:

templates/test/index.html.twig

<form action="{{ url('test_register') }}" method="post">
    <input type="hidden" name="token" value="{{ csrf_token('reg-token') }}">
    <label for="email">Email:</label>
    <input type="email" name="email" id="email">
    <button type="submit">Register</button>
</form>

Method 1 - isCsrfTokenValid method

The AbstractController provides the⁣ isCsrfTokenValid method, which allows manually validating the submitted CSRF token against the expected token ID used in the template.

src/Controller/TestController.php

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException;

class TestController extends AbstractController
{
    #[Route('/')]
    public function index(): Response
    {
        return $this->render('test/index.html.twig');
    }

    #[Route('/register', name: 'test_register')]
    public function register(Request $request): Response
    {
        if (!$this->isCsrfTokenValid('reg-token', $request->request->getString('token'))) {
            throw new InvalidCsrfTokenException('Invalid CSRF token.');
        }

        return new Response('Registered successfully');
    }
}

Method 2 - IsCsrfTokenValid attribute

Symfony also provides the IsCsrfTokenValid attribute for validating CSRF tokens. This approach keeps the controller logic cleaner by moving the validation logic to metadata.

src/Controller/TestController.php

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsCsrfTokenValid;

class TestController extends AbstractController
{
    #[Route('/')]
    public function index(): Response
    {
        return $this->render('test/index.html.twig');
    }

    #[IsCsrfTokenValid('reg-token', tokenKey: 'token')]
    #[Route('/register', name: 'test_register')]
    public function register(Request $request): Response
    {
        return new Response('Registered successfully');
    }
}

Leave a Comment

Cancel reply

Your email address will not be published.