Skip to content

Add antiforgery (anti-csrf) support to minimal endpointsΒ #38630

@halter73

Description

@halter73

Today, Antiforgery is implemented as a filter in MVC. There's an attribute that also acts as an auth filter. It reads the form and performs a validation. Razor Pages add an implicit antiforgery filter that is active for all non-idempotent (POST / PUT / DELETE etc) requests. We'd like to enable Antiforgery to become available outside of MVC. My goal was to continue relying on these attributes, but as metadata that indicated if the user intended to perform antiforgery validation for that endpoint.

In minimal endpoints, this might look like:

app.MapPost("/post", (IFormFile formFile) => { ... })
    .ValidateAntiforgery(); // Maybe we can infer this based on the presence of things that come from a HTTP form.

Generating the antiforgery token that goes in to the form is still tied to the app framework. MVC will generate if you're using the form tag helper / Html.BeginForm(). For a form post using minimal, a user can use the IAntiforgery service to produce it. This PR doesn't attempt to make that experience better.

#38314 (comment)

Thanks @pranavkm for the Antiforgery middleware PR and the nice description in the comments. And extra thanks to @martincostello for adding support for form file parameters to minimal endpoints with #35158!

Now that it is possible to accept IFormFile and IFormFileCollection parameters in minimal actions, we will need to require an antiforgery token for all authenticated endpoints taking these parameter types. Right now, because we don't check for an antiforgery token on these endpoints, we reject any request with a cookie, cert or auth header.

I don't think we'll end up needing the .ValidateAntiforgery() extension method, but maybe that would be useful for endpoints manually consuming a form from the HttpRequest.

Since minimal endpoints are not opinionated about the client app language or framework, having a single solution for generating and sending the antiforgery token is difficult. The current IAntiforgery service interface is built around idea that the client will be performing a request before posting form data and will be able to send a cookie set during that prior request during the actual POST. This makes sense for web clients, but we want to make uploading files easier for non-web clients as well because "multipart/form-data" is one of the most widely adopted ways to upload files over HTTP.

My understanding is that the cookie is there to prevent an attacker from laundering an antiforgery token meant for a different user. It would be more convenient if this could be done without a cookie and instead with a single token tied to the IPrincipal in some other way.

@blowdart

Metadata

Metadata

Assignees

Labels

DocsThis issue tracks updating documentationNeeds: DesignThis issue requires design work before implementating.Priority:0Work that we can't release withoutarea-minimalIncludes minimal APIs, endpoint filters, parameter binding, request delegate generator etcfeature-minimal-actionsController-like actions for endpoint routingold-area-web-frameworks-do-not-use*DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labelstriage-focusAdd this label to flag the issue for focus at triage

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions