Weave 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

Csrf Route Bundle Laravel Package

enumag/csrf-route-bundle

enumag/csrf-route-bundle (GenedysCsrfRouteBundle) secures Symfony 3 routes against CSRF attacks without forms. Add a csrf_token option to any route; the bundle's router appends a token query parameter and a controller listener validates it on incoming requests.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Framework mismatch is the decisive finding. Despite the brief's "Laravel/PHP package" framing, enumag/csrf-route-bundle is a Symfony 3 bundle (published as genedys/csrf-route-bundle). It registers a compiler pass in Symfony's DI container, decorates Symfony's router service, reads Symfony routing options, and validates in a kernel request/controller listener. There is no Laravel ServiceProvider, no publishable config, no facade, and no Illuminate\Foundation-compatible middleware. It cannot be composer required into a Laravel app in any meaningful sense.

Architecture fit: The problem it targets — per-route CSRF validation outside of form submissions (logout links, one-click delete/archive/toggle actions, XHR mutations, GET-triggered state changes) — is a real Laravel-relevant gap in legacy or hurriedly-built applications. Laravel's built-in VerifyCsrfToken middleware already covers POST/PUT/PATCH/DELETE, and @csrf/csrf_token()/X-XSRF-TOKEN cover the form and XHR cases. What Laravel does not give you out of the box is per-route opt-in protection for GET routes or a declarative route-level annotation. That is genuinely a ~40–80 line custom middleware in Laravel. So the package's contribution to a Laravel team is a design precedent, not an installable asset.

Integration feasibility: Effectively zero for direct adoption. Concretely:

  • Symfony 3 reached EOL in November 2018 (3.4 LTS in November 2021); any transitive framework pin is unpatched.
  • The bundle's router decoration assumes Symfony's RouterInterface, RouteCollection, and RequestContext; Laravel's router is a different abstraction with different route action semantics.
  • Annotation-based configuration (@CsrfToken) requires Doctrine annotations plus Symfony's annotation route loader — a stack Laravel does not run.
  • Forcing it in would mean pulling symfony/http-kernel, symfony/routing, and symfony/security-csrf into a Laravel app and bridging kernels. That is a security-debt-for-security-value trade, which should be rejected on principle.

Technical risk: High, and concentrated in the trust boundary. CSRF tokens sit directly on the authentication/authorization path; an unmaintained, unauditable dependency there is a bad risk posture even for small code. Signals:

  • 0 stars, 0 dependents, maturity grade readme, score 0.03 — zero production validation, zero downstream bug reports (which is not the same as zero bugs).
  • Repo name (enumag/csrf-route-bundle) does not match the README's install target (genedys/csrf-route-bundle). That is a supply-chain identity mismatch and must be resolved before the name ever appears in a lockfile review. It suggests a fork whose steward and patch cadence are unknown.
  • No published releases visible, no CVE feed, no issue triage. Any future vulnerability is discovered by us, not upstream.
  • README does not confirm hash_equals constant-time comparison, session binding, or rotation-on-privilege-change — the three things an auditor will ask about.

Key questions to answer before spending any effort:

  1. Is our target stack actually Laravel, or is there a Symfony 3 application in maintenance mode somewhere in the estate? This single answer flips the outcome from "port the pattern" to "do not engage."
  2. What are the non-form, state-mutating routes we actually need to protect, and are any of them GET? Laravel's default middleware does not protect GET.
  3. Does our current CSRF implementation use hash_equals, and what is the token lifetime/rotation policy? (We need parity with or improvement over the precedent.)
  4. Which surface is in scope — server-rendered HTML only, or XHR/fetch? The latter changes the header strategy (X-CSRF-TOKEN vs X-XSRF-TOKEN) and cookie/SameSite handling.
  5. Do we have a pentest finding or SOC 2 / ISO 27001 control line item ("all state-changing requests require a token") that this closes? If yes, this becomes a scheduled remediation with an owner.

Integration Approach

Stack fit: Reject as a Composer dependency. Adopt as a reference implementation for a native Laravel middleware. The transferable surface API is clean and worth copying: per-route opt-in via route action/metadata, token attached at URL-generation time, validated before the controller runs, with configurable field name, intention/scope, and HTTP methods.

Migration path — build the equivalent in Laravel:

  1. Middleware — EnsureRouteCsrfToken (or extend the existing VerifyCsrfToken deny-list with a route-scoped allow-list). Resolve the route, read $route->getAction('csrf_token') or a csrf middleware alias; if present, pull the token from the configured field/header and validate with hash_equals against session()->token().
  2. Route declaration surface — an ergonomic opt-in, e.g. ->middleware('csrf:strict') or ->withTrashed()-style custom method ->csrf(). Prefer native middleware aliases over custom route action keys for discoverability and for route:list visibility.
  3. Token issuance helper — for GET-protected links, add a Blade directive or helper (@csrfLink(), csrf_url()) that appends the token, replacing the Symfony router-decoration mechanism. Do not globally rewrite every generated URL — that leaks tokens into referrers, logs, and browser history for routes that don't need it.
  4. Intention scoping — mirror the bundle's intention option with a signed payload (url, intention, expiry) to prevent cross-route token replay. Symfony's is session-keyed; ours should be explicitly scoped.
  5. XHR path — for fetch/AJAX mutations, enforce the X-XSRF-TOKEN header and add explicit Origin/Referer checks. Sanctum already covers SPAs; do not duplicate.

Compatibility: Target PHP 8.1+ on a supported Laravel (10/11/12). No Symfony packages introduced. No lockfile change. The only shared artifact with the source repo is the idea — MIT license permits reimplementation; we should attribute the inspiration in the design doc for provenance, not vendor the code.

Sequencing (2 sprints, small):

  • Sprint 1: Inventory existing routes; classify state-mutating vs read-only; identify non-form mutation paths and any GET-mutations. Write the middleware, helper, intention signing, and tests (GET-looks-safe action, XHR call, logout path, token replay across routes, expired token, missing token).
  • Sprint 2: Roll out behind a feature flag to the highest-risk route groups first (admin panels, destructive link actions), monitor 419/403 spike rate, then widen. Document the control for audit.

Explicit non-path: installing the bundle, bridging Symfony's kernel, or writing a Laravel adapter around GenedysCsrfRouteBundle. The engineering cost of the adapter exceeds the cost of a clean native implementation, and the adapter inherits the EOL framework and unmaintained-dependency risk without any offsetting benefit.

Operational Impact

Maintenance: We own it — which is the point. The native middleware is ~80 lines plus tests, inside our codebase, on our supported framework version, reviewed by our security reviewers. Maintenance burden is near-zero and, critically, bounded: a framework upgrade touches our code, not an abandoned third-party bundle pinned to a dead Symfony major.

Support: With the source package there is no maintainer, no issue triage, and 0 dependents — meaning no community to shake out bugs or publish patches. Any defect becomes ours to find, diagnose, and fork. With the native implementation, the same is true but the blast radius is one file we wrote and understand, not a graph of Symfony 2/3-era transitive dependencies.

Scaling: The middleware approach scales linearly and cheaply: stateless per-request validation, single session read, hash_equals comparison. Costs are negligible relative to request handling. Watch one thing — if token URLs are appended to high-volume generated links (email templates, paginated lists, sitemaps), you get token sprawl into caches and logs. That's the reason to scope issuance narrowly rather than globally decorate the router the way the bundle does.

Failure modes to design against:

  • Over-application — token appended to every generated URL bloats responses and leaks tokens to referrers, CDNs, analytics, and access logs. Mitigation: opt-in only, no global decoration.
  • Token-in-GET exposure — a CSRF token in a URL ends up in Referer headers and browser history. Mitigation: treat GET-protected actions as a stopgap; prefer converting them to POST/DELETE. Document the residual risk explicitly for audit.
  • Cross-route replay — a token valid for route A accepted on route B. Mitigation: signed intention scoping.
  • Cache poisoning of tokens — a cached HTML page carries a stale token; users hit 419. Mitigation: Cache-Control: no-store on token-bearing pages, and a friendly 419 recovery path (re-render, don't hard-fail).
  • Session/token mismatch after privilege change — token issued pre-login accepted post-login. Mitigation: session()->regenerate() on auth events, which Laravel already does — verify it covers the token too.
  • Silent disablement — an enabled: false toggle (as the bundle offers) is a foot-gun that lets CSRF protection be switched off in an incident and never switched back. Mitigation: no global kill switch; use per-route allow-listing with a documented exception register.

Ramp-up: Minimal for a mid-level Laravel engineer — the middleware pattern is idiomatic and the test matrix is the only real work. Estimated 1–2 engineer-days. The security team's involvement is a doc review plus confirmation of scope (HTML-only vs XHR), which is the one decision that materially changes the design.

Bottom-line decision for the log: Reject enumag/csrf-route-bundle as a dependency — framework mismatch (Symfony 3, not Laravel), EOL platform, package-identity mismatch between repo and install name, and no stewardship (0 stars, 0 dependents, README-only maturity). Accept it as a validated design precedent for a native Laravel middleware covering non-form, state-mutating routes. Owner: platform team. Timeline: next hardening sprint. Success criteria: all identified non-form mutation paths token-validated, hash_equals comparison, intention-scoped tokens, no-store on token-bearing pages, and a documented exception register replacing any global on/off switch.

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.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core