Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Security Csrf Laravel Package

symfony/security-csrf

Symfony Security CSRF component provides CsrfTokenManager to generate, store, and validate CSRF tokens, protecting forms and requests against cross-site request forgery. Integrates cleanly with Symfony apps and can be used standalone in PHP projects.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps to First Use

  1. Install the Package

    composer require symfony/security-csrf
    

    For Laravel, ensure compatibility with your Symfony components (e.g., symfony/http-foundation).

  2. Register the Service Bind the CsrfTokenManagerInterface to a concrete implementation in Laravel’s service container (e.g., app/Providers/AppServiceProvider.php):

    use Symfony\Component\Security\Csrf\CsrfTokenManager;
    use Symfony\Component\Security\Csrf\TokenGenerator\UriSafeTokenGenerator;
    
    public function register()
    {
        $this->app->singleton(CsrfTokenManagerInterface::class, function ($app) {
            $tokenGenerator = new UriSafeTokenGenerator();
            return new CsrfTokenManager($tokenGenerator);
        });
    }
    
  3. Generate a Token Inject CsrfTokenManagerInterface into a controller or service:

    use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
    
    public function showForm(CsrfTokenManagerInterface $csrfTokenManager)
    {
        $token = $csrfTokenManager->getToken('form_token')->getValue();
        return view('form', ['csrf_token' => $token]);
    }
    
  4. Validate a Token In a form handler or API endpoint:

    public function submitForm(Request $request, CsrfTokenManagerInterface $csrfTokenManager)
    {
        $token = $request->request->get('_csrf_token');
        if (!$csrfTokenManager->isTokenValid(new CsrfToken('form_token', $token))) {
            throw new \Symfony\Component\Security\Core\Exception\AccessDeniedException('Invalid CSRF token.');
        }
        // Process the form...
    }
    
  5. Laravel Integration (Optional) Extend Laravel’s built-in CSRF middleware (app/Http/Middleware/VerifyCsrfToken.php) to use Symfony’s token manager:

    use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
    
    protected function validateCsrfToken($request, $exception)
    {
        $token = $request->input('_csrf_token');
        if (!$this->csrfTokenManager->isTokenValid(new CsrfToken('laravel_csrf_token', $token))) {
            throw $exception;
        }
    }
    

First Use Case: Protecting a Form

  • Scenario: Secure a form submission (e.g., payment, user profile update).
  • Steps:
    1. Generate a token in the form view:
      <input type="hidden" name="_csrf_token" value="{{ $csrf_token }}">
      
    2. Validate the token in the controller:
      $this->validate($request, ['_csrf_token' => 'required|string']);
      if (!$this->csrfTokenManager->isTokenValid(new CsrfToken('form_token', $request->input('_csrf_token')))) {
          abort(403, 'Invalid CSRF token.');
      }
      

Implementation Patterns

Core Workflows

1. Token Generation and Storage

  • Default Behavior: Tokens are generated using UriSafeTokenGenerator (base64-encoded random bytes) and stored in memory or a session.
  • Custom Storage:
    • Implement CsrfTokenStorageInterface for database/Redis storage:
      use Symfony\Component\Security\Csrf\TokenStorage\TokenStorageInterface;
      
      class DatabaseTokenStorage implements TokenStorageInterface
      {
          public function getToken($tokenId): ?CsrfToken
          {
              // Fetch from database...
          }
      
          public function deleteToken($tokenId): void
          {
              // Delete from database...
          }
      }
      
    • Bind the custom storage to CsrfTokenManager:
      $this->app->singleton(CsrfTokenManagerInterface::class, function ($app) {
          $storage = new DatabaseTokenStorage();
          $tokenGenerator = new UriSafeTokenGenerator();
          return new CsrfTokenManager($tokenGenerator, $storage);
      });
      

2. Stateless CSRF Protection (APIs)

  • Use SameSite attributes and headers (e.g., Sec-Fetch-Site) for stateless validation:
    use Symfony\Component\Security\Csrf\TokenGenerator\UriSafeTokenGenerator;
    use Symfony\Component\Security\Csrf\TokenStorage\CookieTokenStorage;
    
    $tokenStorage = new CookieTokenStorage(
        $requestStack,
        'XSRF-TOKEN',
        'X-CSRF-TOKEN',
        ['same_site' => 'lax']
    );
    $csrfTokenManager = new CsrfTokenManager(new UriSafeTokenGenerator(), $tokenStorage);
    
  • Laravel-Specific: Use middleware to inject the token into headers:
    public function handle($request, Closure $next)
    {
        $token = $this->csrfTokenManager->getToken('api_token')->getValue();
        $request->headers->set('X-CSRF-Token', $token);
        return $next($request);
    }
    

3. Token Rotation

  • Rotate tokens after each use (e.g., for sensitive forms):
    $token = $csrfTokenManager->getToken('form_token');
    $csrfTokenManager->deleteToken('form_token'); // Invalidate old token
    

4. Multi-Token Support

  • Use different token IDs for different forms/endpoints:
    // Generate for login form
    $loginToken = $csrfTokenManager->getToken('login_token')->getValue();
    
    // Generate for profile form
    $profileToken = $csrfTokenManager->getToken('profile_token')->getValue();
    

Integration Tips

Laravel-Specific Patterns

  1. Middleware Integration Create a custom middleware to validate CSRF tokens:

    namespace App\Http\Middleware;
    
    use Closure;
    use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
    use Symfony\Component\Security\Csrf\CsrfToken;
    
    class CsrfTokenMiddleware
    {
        public function __construct(protected CsrfTokenManagerInterface $csrfTokenManager)
        {
        }
    
        public function handle($request, Closure $next)
        {
            if ($request->isMethod('post') && !$request->has('_csrf_token')) {
                abort(403);
            }
    
            $token = $request->input('_csrf_token');
            if (!$this->csrfTokenManager->isTokenValid(new CsrfToken('laravel_csrf_token', $token))) {
                abort(403, 'Invalid CSRF token.');
            }
    
            return $next($request);
        }
    }
    

    Register it in app/Http/Kernel.php:

    protected $middleware = [
        // ...
        \App\Http\Middleware\CsrfTokenMiddleware::class,
    ];
    
  2. Blade Directives Create a Blade directive for token generation:

    Blade::directive('csrfToken', function ($expression) {
        $token = app(CsrfTokenManagerInterface::class)->getToken($expression)->getValue();
        return "<?php echo '{$token}'; ?>";
    });
    

    Usage in views:

    <input type="hidden" name="_csrf_token" value="{{ csrfToken('form_token') }}">
    
  3. API Resource Protection For APIs, use a header-based approach:

    // Middleware
    public function handle($request, Closure $next)
    {
        $token = $request->header('X-CSRF-TOKEN');
        if (!$this->csrfTokenManager->isTokenValid(new CsrfToken('api_token', $token))) {
            abort(403);
        }
        return $next($request);
    }
    

Testing Patterns

  1. Unit Testing Tokens Mock CsrfTokenManager in tests:

    $tokenManager = $this->createMock(CsrfTokenManagerInterface::class);
    $tokenManager->method('isTokenValid')->willReturn(true);
    
    $this->app->instance(CsrfTokenManagerInterface::class, $tokenManager);
    
  2. Integration Testing Test token validation with real requests:

    public function test_csrf_protection()
    {
        $response = $this->post('/submit-form', [
            '_csrf_token' => $this->csrfTokenManager->getToken('form_token')->getValue(),
            'data' => 'test',
        ]);
        $response->assertStatus(200);
    }
    

Gotchas and Tips

Pitfalls

  1. Token Storage Assumptions

    • Issue: Symfony’s CsrfTokenManager defaults to in-memory storage, which is not persistent across requests.
    • Fix: Use a session or database-backed storage (e.g., SessionTokenStorage or a custom implementation).
    • Laravel Note: Laravel’s session driver works but may require adapter logic.
  2. Token ID Collisions

    • Issue: Using the same token ID (e.g., 'form_token') for multiple forms can cause validation failures if tokens are rotated.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope