[6.x] Fix /!/nocache and /!/csrf CSRF exemption on Laravel 13#14533
Merged
jasonvarga merged 1 commit intostatamic:6.xfrom Apr 22, 2026
Merged
[6.x] Fix /!/nocache and /!/csrf CSRF exemption on Laravel 13#14533jasonvarga merged 1 commit intostatamic:6.xfrom
jasonvarga merged 1 commit intostatamic:6.xfrom
Conversation
Laravel 13 renamed the CSRF middleware from ValidateCsrfToken to Illuminate\Foundation\Http\Middleware\PreventRequestForgery. The legacy VerifyCsrfToken and ValidateCsrfToken classes are now @deprecated subclasses of PreventRequestForgery. The route exemptions here use withoutMiddleware([VerifyCsrfToken]), and Laravel's Router::resolveMiddleware excludes via ReflectionClass::isSubclassOf — but PreventRequestForgery is the *parent* of the listed classes, not a subclass, so the check returns false and the exemption is a no-op. The CSRF check fires on the unauthenticated POST and Laravel throws TokenMismatchException, so the client-side nocache bootstrap cannot hydrate regions under full static caching, and /!/csrf cannot refresh the token either. Adding PreventRequestForgery to both lists fixes Laravel 13 while keeping the existing entries for Laravel 10-12 compatibility via the deprecated aliases.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Laravel 13 renamed the CSRF middleware to
Illuminate\Foundation\Http\Middleware\PreventRequestForgery.VerifyCsrfTokenandValidateCsrfTokenare now@deprecatedaliases that extendPreventRequestForgery.routes/web.phpexempts the legacy classes on/!/nocacheand/!/csrf:Laravel's
Router::resolveMiddlewarefilters excluded middleware viaReflectionClass::isSubclassOf— asking "is the registered middleware a subclass of anything in the excluded list?" On Laravel 13, the registered middleware isPreventRequestForgeryand the excluded classes are its subclasses, not its parents, so the check returns false and the exemption is a no-op.PreventRequestForgery::handleruns against an unauthenticated POST, throwsTokenMismatchException, and Laravel returns 419.Symptoms
STATAMIC_STATIC_CACHING_STRATEGY=full, the client-side nocache bootstrap POSTs to/!/nocacheand gets 419. Regions never hydrate./!/csrf(the token-refresh endpoint) has the same stale exempt list and the same failure mode.Likely related to #10801 (full-cache CSRF mismatch), reported on Laravel 11 / Statamic 5; that symptom surface differs, but the underlying drift —
withoutMiddlewareno longer matching the active CSRF class — is the same root cause and is tripped again by the Laravel 13 rename.Repro
Laravel 13 + Statamic 6:
Reproduces with
STATAMIC_STATIC_CACHING_STRATEGY=null, so no caching needed.app('router')->gatherRouteMiddleware($route)on thestatamic.nocacheroute returns[EncryptCookies, AddQueuedCookiesToResponse, StartSession, ShareErrorsFromSession, PreventRequestForgery, SubstituteBindings, NoCacheLocalize]—PreventRequestForgeryis still in the list.Fix
Add
Illuminate\Foundation\Http\Middleware\PreventRequestForgeryto bothwithoutMiddlewarelists. The legacy entries stay for Laravel 10–12 compatibility through the deprecated aliases.Notes
@deprecatedand will likely be removed in a future Laravel major, which would turn the existing list into dead entries.PreventRequestForgerydoes not exist in the active stack.