slim/csrf
Slim CSRF provides CSRF protection for Slim 4 apps via PSR-15 middleware. It generates and validates tokens, supports session-based or custom storage, and can inject hidden token fields into forms and views.
Architecture fit. slim/csrf is a CSRF guard built for Slim Framework 4 as PSR-15 middleware over PSR-7 ServerRequestInterface/ResponseInterface, with token state behind a pluggable storage abstraction and a configurable failure callable. Laravel's HTTP kernel is middleware-based in spirit but uses Symfony HttpFoundation and its own middleware contract (handle($request, Closure $next)), and ships VerifyCsrfToken in the web group with token issuance, XSRF-TOKEN cookie encryption, except URI lists, and session regeneration hooks already wired. There is no structural overlap that makes this package a drop-in improvement — it solves the same problem in a different framework's idiom.
Integration feasibility. Direct use in a Laravel app requires three adapters that the package does not provide: (1) a PSR-7/PSR-17 bridge (symfony/psr-http-message-bridge plus a message factory) to convert Laravel requests into PSR-7 objects and back, (2) a StorageInterface implementation backed by Laravel's session repository rather than the package's default PHP session array, and (3) a token delivery contract — the Guard exposes a per-request name/value pair via getTokenNameKey()/getTokenValueKey(), which differs from Laravel's single _token field and X-XSRF-TOKEN header convention, so every Blade form, Inertia share, and axios interceptor would need to change. Feasible in a hybrid deployment where an existing Slim service is mounted alongside Laravel; not sensible as a replacement for the native guard.
Technical risk. Moderate-to-high for the replacement path, low for the "reference implementation" path. The guard itself does the security-critical things correctly (constant-time comparison, per-request token rotation with optional persistent mode, explicit failure callback), but wrapping it in a bridge means the security boundary now includes our adapter code, session binding, and header translation — all of which are new failure surface with no upstream test coverage. Regressions are quiet: a mis-scoped StorageInterface that reads from a different session key than the one Laravel writes to produces intermittent 419s rather than a clean error, and per-request token rotation breaks multi-tab workflows unless persistent mode is explicitly enabled.
Key questions.
X-CSRF-TOKEN, X-XSRF-TOKEN), and can they accept a second name/value pair?opportunity: 29.3 and 0 declared dependents, is there any ecosystem signal suggesting this package is a strategic choice rather than an artifact of a framework-specific search?Stack fit. Laravel 10/11/12 on PHP 8.1+, Redis-backed sessions, a Blade or Inertia/Vue front end. The package itself is framework-agnostic PHP with PSR-7/PSR-15 dependencies and no Laravel service provider, config file, or facade — nothing auto-discovers, so all wiring is manual. This is appropriate only where we control both the middleware registration and the front-end token contract.
Migration path. Three viable postures, in ascending order of cost:
slim/csrf as a design reference and keep VerifyCsrfToken. Extract the ideas worth borrowing — persistent-token mode for multi-tab tolerance, explicit failure callable for 419 UX — and implement them as a thin subclass in app/Http/Middleware.StartSession and before authorization; mount the PSR-7 bridge as an outer middleware; write a LaravelSessionStorage adapter; map the failure callable to a 419 JSON/HTML response matching Laravel's convention so clients cannot distinguish the two.Compatibility. Verify PHP constraint against the platform's minimum, PSR-7 implementation compatibility with existing HTTP clients in the codebase, and middleware ordering — CSRF must run after session start and before any state-changing controller, and must be excluded for signed webhook and token-authenticated API routes. Laravel's testing helpers (withoutMiddleware, withSession, assertSessionHas) will not understand the guard's storage, so a test helper is required or the test suite degrades.
Sequencing.
VerifyCsrfToken for two weeks.VerifyCsrfToken as a fallback for one release cycle.Maintenance. The package is small, MIT-licensed, and current (release dated 2025-11-05), which is a positive signal for upstream health. The ongoing burden is not the dependency — it is the adapter code we own: the PSR-7 bridge, the session storage implementation, the failure handler, and the dual-read front-end logic. That is several hundred lines of bespoke security-adjacent code maintained by our team indefinitely, versus zero lines for the native guard. Upstream bug fixes will frequently not apply to our integration path without rework.
Support. Community-only, no vendor SLA, and with 0 declared dependents there is limited evidence of a large production user base to lean on for incident precedent. Bus factor is concentrated in the Slim maintainer group. We would need an internal runbook covering token lifecycle, storage keys, and the 419 triage tree before any production traffic, and an explicit owner for the adapter layer.
Scaling. Effectively neutral. Token generation is a few random bytes per request; the only scaling consideration is that the storage adapter must read from the shared session store (Redis) rather than process-local state, or a load-balanced deployment will produce cross-node token mismatches that look like random user logouts. Persistent token mode reduces session-write churn and is preferable at high request volume where most requests are reads.
Failure modes.
Cache-Control: no-store on any token-bearing response.Ramp-up. Backend engineers need PSR-7/PSR-15 fluency plus a walkthrough of the bridge before touching the middleware — roughly 1–2 days for a senior engineer, longer for anyone whose mental model is Laravel middleware only. Front-end needs the revised token contract documented with examples for form posts, axios, and Inertia. Support and on-call need the 419 triage runbook. Budget two to three weeks of elapsed time end-to-end for the bridge path, versus roughly two days to extend the native guard with the two features actually worth borrowing. Given the low opportunity score and the absence of any hard requirement to run Slim CSRF inside Laravel, the defensible recommendation is to decline adoption for the Laravel estate and revisit only if a genuine Slim service enters the portfolio.
How can I help you explore Laravel packages today?