dotnet / dotnet/aspnetcore

CORS: Headers are not set after client has been redirected from http to https

Open
#54,509 0 comments 0 reactions 0 assignees View on GitHub
area-mvc feature-cors
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 6h
Merged PRs (30d)
290

Description

### Is there an existing issue for this?

- [X] I have searched the existing issues

### Describe the bug

I've made an oversight by doing a GET request via http:// instead of https:// and wasn't able to use CORS even after being redirected automatically. It however works fine when i correctly use the https:// scheme in my fetch call to begin with.

The application is set-up behind a Caddy reverse proxy, that automatically redirects insecure http requests to https. (resulting in a 307 - Internal Redirect from javascript's fetch function)

Unfortunately, ASP.NET does not return any CORS headers after being redirected (which might also be good in terms of security - but confusing for the developer)

A [section in the official docs](https://learn.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-8.0#http-redirection-to-https-causes-err_invalid_redirect-on-the-cors-preflight-request) mentions that CORS requests to the insecure http scheme will fail with ERR_INVALID_REDIRECT when using `app.UseHttpsRedirection()`, but since i don't use this feature, as this is the sole responsibility of my reverse proxy, this is not what happens at all.

Instead, my browser (chrome dev) throws an error like:

```
Access to fetch at 'https://api.example.dev/api/v1/product-categories/'
(redirected from 'http://api.example.dev/api/v1/product-categories/')
from origin 'http://localhost:8000' has been blocked by CORS policy:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
```

### Expected Behavior

I expected that ASP.NET Core allowed http to https redirects for the same target host / origin and keeps CORS functional. This allows the client to follow redirects and still use CORS.

### Steps To Reproduce

Client Side (running localhost:8000 with python3 -m http.server):
```js
fetch('http://glas-online.invadox.dev/api/v1/product-categories/')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.log('Error:', error));
```

Server Side: (webapi template)
```csharp
// Program.cs
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddScoped();
builder.Services.AddControllers();

builder.Services.AddCors(opts =>
{
opts.AddDefaultPolicy(policy =>
{
var allowedHosts = builder.Configuration["Cors:AllowedOrigins"];

if (!string.IsNullOrWhiteSpace(allowedHosts))
{
policy.WithOrigins(allowedHosts.Split(","));
}
else
{
policy.AllowAnyOrigin();
Console.WriteLine("[Warn] Cors:AllowedOrigins not set in appsettings.json, allowing any origin");
}

policy.AllowAnyMethod();
policy.AllowAnyHeader();
});
});

var app = builder.Build();

app.UseCors();
app.UseAuthorization();
app.MapControllers();

app.Run();
```

Server Side: appsettings.json
```json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"Cors": {
"AllowedOrigins": "http://localhost:3000,http://localhost:8000"
}
}
```

Server Side: Caddy Config
```
api.example.dev {
reverse_proxy 127.0.0.1:5000
}
```

### Exceptions (if any)

_No response_

### .NET Version

8.0.200

### Anything else?

_No response_

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.