Skip to content

HTTP 500 if request to a CORS-enabled endpoint is requested without an origin header #9348

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

Closed
martincostello opened this issue Apr 13, 2019 · 3 comments · Fixed by #9440
Closed
Assignees
Labels
area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates bug This issue describes a behavior which is not expected - a bug. Done This issue has been fixed

Comments

@martincostello
Copy link
Member

Describe the bug

If an HTTP request is made to a CORS-enabled endpoint where an origin HTTP request header is not specified, the request fails with an HTTP 500 error.

The exception in the logs is:

[2019-04-13 14:40:04Z] fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
      An unhandled exception has occurred while executing the request.
System.InvalidOperationException: Endpoint MartinCostello.Api.Controllers.TimeController.Get (API) contains CORS metadata, but a middleware was not found that supports CORS.
Configure your application startup by adding app.UseCors() inside the call to Configure(..) in the application startup code.
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.ThrowMissingCorsMiddlewareException(Endpoint endpoint)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.HttpOverrides.HttpMethodOverrideMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

However, app.Cors() has been added to the application before app.UseEndpoints(...).

This appears to have been introduced by #9181.

If the request has no origin request header, then the CORS middleware is skipped:

https://github.com/aspnet/AspNetCore/blob/b93bc433db66175d2b07b128ec9990f7a4dd7e1b/src/Middleware/CORS/src/Infrastructure/CorsMiddleware.cs#L122-L125

However, the endpoint middleware finds the CORS metadata on the endpoint being invoked, and checks whether the CORS middleware was invoked (which it was, but was skipped as not needed) by looking for a key in the HttpContext's items. The item isn't present, so an exception is thrown:

https://github.com/aspnet/AspNetCore/blob/84da613d2c03b6f1c0fa3c01828923ec3415d525/src/Http/Routing/src/EndpointMiddleware.cs#L51-L55

The key being tested by the endpoint middleware is only added if the origin header is present in the request, which is here:

https://github.com/aspnet/AspNetCore/blob/b93bc433db66175d2b07b128ec9990f7a4dd7e1b/src/Middleware/CORS/src/Infrastructure/CorsMiddleware.cs#L140-L141

It would appear that two possible fixes are either:

  1. The CORS middleware always adds the "I've run" value to HttpContext.Items, or:
  2. The endpoint middleware also checks for the origin header if CORS metadata is present on the endpoint, and only throws the exception for the non-invocation of the CORS middleware if it is present in the HTTP request.

To Reproduce

  1. Configure an ASP.NET Core MVC application to use CORS.
  2. Add the [EnableCors(...)] attribute to a controller method.
  3. Launch the application.
  4. Perform a standard HTTP request (e.g. with cURL) to the endpoint.

Expected behavior

The request succeeds if no origin HTTP request header is provided.

Additional context

.NET Core SDK (reflecting any global.json):
 Version:   3.0.100-preview4-011204
 Commit:    621575bab1

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.17763
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\3.0.100-preview4-011204\

Host (useful for support):
  Version: 3.0.0-preview4-27612-09
  Commit:  64e9c3e1cd
@martincostello
Copy link
Member Author

Issue was found as part of making this commit to a simple sandbox app: martincostello/api@a40a99f

@davidfowl
Copy link
Member

cc @pranavkm

@blowdart blowdart added the area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates label Apr 15, 2019
@mkArtakMSFT mkArtakMSFT added the bug This issue describes a behavior which is not expected - a bug. label Apr 15, 2019
@mkArtakMSFT mkArtakMSFT added this to the 3.0.0-preview5 milestone Apr 15, 2019
@pranavkm pranavkm added Done This issue has been fixed and removed 2 - Working labels Apr 16, 2019
@pranavkm
Copy link
Contributor

For preview4, possible workarounds include:

  1. Having a middleware that sets the value in HttpContext.Items after UseCors()
app.UseCors();

app.Use((context, next) =>
{
    context.Items["__CorsMiddlewareInvoked"] = true;
    return next();
});
  1. Disable the check in EndpointRouting:
services.AddRouting(r => r.SuppressCheckForUnhandledSecurityMetadata = true);

The first one would be preferred since it's not removing a check for a mis-configured application.

@ghost ghost locked as resolved and limited conversation to collaborators Dec 3, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates bug This issue describes a behavior which is not expected - a bug. Done This issue has been fixed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants