Scope default CSRF middleware to endpoints opting in via IAntiforgeryMetadata#67460
Merged
DeagleGross merged 4 commits intoJun 30, 2026
Conversation
CsrfProtectionMiddleware now mirrors the classic AntiforgeryMiddleware: it only runs DefaultCsrfProtection.ValidateAsync when the matched endpoint carries IAntiforgeryMetadata with RequiresValidation = true. Endpoints with no metadata, or with DisableAntiforgery() (RequiresValidation = false), pass through without recording an IAntiforgeryValidationFeature verdict. The MiddlewareInvokedKeys.CsrfProtection sentinel continues to be set unconditionally so the FormFeature antiforgery backstop (dotnet#67082) still recognizes that an antiforgery-style middleware ran on the request. Tests updated to attach RequireAntiforgeryTokenAttribute on endpoints whose intent is to exercise the validation path, and new tests added covering (a) no-metadata pass-through, (b) DisableAntiforgery pass-through, and (c) opted-in cross-site denial — all three asserting the sentinel is still set. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Scopes the auto-injected CsrfProtectionMiddleware so it mirrors AntiforgeryMiddleware: it only performs CSRF validation when the matched endpoint opts in via IAntiforgeryMetadata.RequiresValidation == true, preventing previously-working endpoints (e.g., plain MapPost, unannotated [HttpPost]) from becoming newly blocked.
Changes:
- Update
CsrfProtectionMiddlewareto skip validation unless the matched endpoint hasIAntiforgeryMetadata { RequiresValidation: true }. - Adjust integration tests to explicitly attach
RequireAntiforgeryTokenAttributewhere tests intend to exercise the “validation runs” path, and add new tests covering “no metadata / opted out” pass-through behavior.
Show a summary per file
| File | Description |
|---|---|
| src/DefaultBuilder/src/Internal/CsrfProtectionMiddleware.cs | Changes validation gating to require endpoint opt-in via IAntiforgeryMetadata.RequiresValidation == true. |
| src/DefaultBuilder/test/Microsoft.AspNetCore.Tests/CsrfProtectionIntegrationTests.cs | Updates existing tests to opt endpoints in where needed and adds coverage for pass-through/no-verdict scenarios. |
Copilot's findings
- Files reviewed: 2/2 changed files
- Comments generated: 1
javiercn
approved these changes
Jun 29, 2026
campersau
reviewed
Jun 29, 2026
halter73
approved these changes
Jun 29, 2026
Split CsrfProtectionMiddleware.InvokeAsync into a synchronous wrapper
that sets the sentinel, checks endpoint metadata, and returns _next(context)
directly when validation is not required. The async core moves to a
private InvokeCoreAsync that handles the await chain only when an
endpoint opts in via IAntiforgeryMetadata { RequiresValidation: true }.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- EnforceCsrf now returns 'passthrough' | 'allowed' | 'protected' so body assertions disambiguate skip vs allow vs deny outcomes. - Add EnforceCsrfProtected ([RequireAntiforgeryToken]) and EnforceCsrfForm ([FromForm]) helpers; replace .WithMetadata(new RequireAntiforgeryTokenAttribute()) call sites that route through these handlers. - CreateApp uses the new helpers and adds a /passthrough route (no metadata) exercising the alt-design skip path. - Add CsrfProtection_RdfInferredFormMetadata_CrossOriginUntrustedOrigin_Protects to cover the RequestDelegateFactory InferAntiforgeryMetadata path. - Add inline body assertions matching the new tri-state values. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
javiercn
approved these changes
Jun 30, 2026
javiercn
pushed a commit
that referenced
this pull request
Jun 30, 2026
…yMetadata` (#67460) Aligns CsrfProtectionMiddleware with classic AntiforgeryMiddleware: validation runs only when the matched endpoint has IAntiforgeryMetadata { RequiresValidation: true }. Endpoints without metadata (plain MapPost, plain [HttpPost]) pass through, matching .NET 10 behavior — so no customer endpoint that worked on .NET 10 will start failing on .NET 11. Blazor SSR and RDF form binding stay protected because they already attach RequireAntiforgeryTokenAttribute automatically. The MiddlewareInvokedKeys.CsrfProtection sentinel is still set unconditionally to preserve the FormFeature backstop contract from #67082.
This was referenced Jul 15, 2026
Merged
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.
Aligns
CsrfProtectionMiddlewarewith classicAntiforgeryMiddleware: validation runs only when the matched endpoint hasIAntiforgeryMetadata { RequiresValidation: true }. Endpoints without metadata (plainMapPost, plain[HttpPost]) pass through, matching .NET 10 behavior — so no customer endpoint that worked on .NET 10 will start failing on .NET 11.Blazor SSR and RDF form binding stay protected because they already attach
RequireAntiforgeryTokenAttributeautomatically. TheMiddlewareInvokedKeys.CsrfProtectionsentinel is still set unconditionally to preserve theFormFeaturebackstop contract from #67082.Fixes #67424