Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Blazor] Avoid validating antiforgery for non form data content types #55604

Merged
merged 7 commits into from
May 9, 2024

Conversation

javiercn
Copy link
Member

@javiercn javiercn commented May 8, 2024

Sends bad request if content-type is not valid (like application/json)

Fixes #55582

@javiercn javiercn requested a review from a team as a code owner May 8, 2024 16:43
@dotnet-issue-labeler dotnet-issue-labeler bot added the area-blazor Includes: Blazor, Razor Components label May 8, 2024
if (!context.Request.HasFormContentType)
{
context.Response.StatusCode = StatusCodes.Status400BadRequest;
if (context.RequestServices.GetService<IHostEnvironment>()?.IsDevelopment() == true)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's some logic in EndpointHtmlRenderer.Streaming.cs like this:

        var env = httpContext.RequestServices.GetRequiredService<IWebHostEnvironment>();
        var options = httpContext.RequestServices.GetRequiredService<IOptions<RazorComponentsServiceOptions>>();
        var showDetailedErrors = env.IsDevelopment() || options.Value.DetailedErrors;

I guess we should use a similar condition here, and maybe it could be factored out into a common place.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is why I hate partial classes, but good call

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've factored out the code, and put it in a static method, I can't think of a good place to put that logic, so I'm going to just randomly leave it inside EndpointHtmlRenderer and use it in the invoker, if we go through this code again, we can do a clean-up pass.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't we also use ShouldShowDetailedErrors as the condition for whether to emit The request has an incorrect Content-type. to the response here, instead of IsDevelopment on line 171?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I updated it in the wrong place

@@ -205,7 +215,7 @@ private async Task<RequestValidationState> ValidateRequestAsync(HttpContext cont
{
context.Response.StatusCode = StatusCodes.Status400BadRequest;

if (context.RequestServices.GetService<IHostEnvironment>()?.IsDevelopment() == true)
if (EndpointHtmlRenderer.ShouldShowDetailedErrors(context))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't spot this before but it's good you've updated it

Copy link
Member

@SteveSandersonMS SteveSandersonMS left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great!

@javiercn javiercn force-pushed the javiercn/fix-form-content-type branch from d84f88f to 1c90e08 Compare May 9, 2024 12:33
@@ -165,7 +164,9 @@ private async Task<RequestValidationState> ValidateRequestAsync(HttpContext cont

if (processPost)
{
if (!context.Request.HasFormContentType)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@captainsafia I think this was triggered by the antiforgery middleware, I believe we should revisit this to avoid throwing and instead return false. It's surprising otherwise and might break existing code, do you have thoughts?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you might be talking about the exception that gets thrown here). If so, I'm a little cautious about changing this behavior given its in the FormFeature shared across the stack as opposed to just being in anti-forgery middleware.

We don't eagerly validate the content type in the anti-forgery middleware (although we could) then we wouldn't fall through to the exception in the FormFeature.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might have been confused and thought the issue might have been related to antiforgery, since I saw an exception pop right before.

I'll take another quick look at it and see if I repro it in a simpler way. I throught it was the thing where we poisoned the IFormFeature that was throwing, but I can't find it right now.

@javiercn javiercn merged commit e8eeea6 into main May 9, 2024
26 checks passed
@javiercn javiercn deleted the javiercn/fix-form-content-type branch May 9, 2024 15:57
@dotnet-policy-service dotnet-policy-service bot added this to the 9.0-preview5 milestone May 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-blazor Includes: Blazor, Razor Components
Projects
None yet
Development

Successfully merging this pull request may close these issues.

.NET 8 Blazor - Static Rendering, AntiForgery and Incorrect Content-Type: Exceptions
3 participants