CORS: Headers are not set after client has been redirected from http to https
- 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
Assessment
This issue has not been assessed yet.