Skip to content

SetIsOriginAllowedToAllowWildcardSubdomains ignores final / (path) for wildcard domains but not for exact matches #65623

@EraYaN

Description

@EraYaN

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

builder.SetIsOriginAllowedToAllowWildcardSubdomains()
                    .WithOrigins(["https://test.example.com/"])
builder.SetIsOriginAllowedToAllowWildcardSubdomains()
                    .WithOrigins(["https://*.example.com/"])

Have different behavior. (note the final slash). Obviously we can trim that but the behavior difference should probably mean it warns or something when the path is there. Especially because the Uri class seems to add that / in it's ToString method.

Expected Behavior

I would expect when the origin header is Origin: https://test.example.com for both of those have the same behavior.
In my opinion both should allow the CORS request, but it should probably also warn the user if it detects that final / and an empty path. Browsers don't seem to send that path. https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Origin seems to be not in the standard

Steps To Reproduce

Project.csproj
<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net10.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

</Project>
Program.cs
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

var testWildcardOrigin = "https://*.example.org/";
var testOrigin = "https://test.example.org/";

builder.Services.AddCors(options =>
{
    options.AddPolicy("wildcard", policy =>
    {
        policy.AllowAnyMethod()
            .AllowAnyHeader()
            .SetIsOriginAllowedToAllowWildcardSubdomains()
            .WithOrigins(testWildcardOrigin)
            .AllowCredentials();
    });
    options.AddPolicy("subdomain", policy =>
    {
        policy.AllowAnyMethod()
            .AllowAnyHeader()
            .SetIsOriginAllowedToAllowWildcardSubdomains()
            .WithOrigins(testOrigin)
            .AllowCredentials();
    });
});

var app = builder.Build();

app.UseCors();

// Configure the HTTP request pipeline.

app.MapGet("/wildcard", () => "test wildcard").RequireCors("wildcard");
app.MapGet("/subdomain", () => "test subdomain").RequireCors("subdomain");

app.Run();

Test curl command: (change port if appropriate)

curl -X OPTIONS -H "Origin: https://test.example.org" -H "Access-Control-Request-Method: GET" -H "Access-Control-Request-Headers: authorization,content-type" -v "http://localhost:5222/wildcard" "http://localhost:5222/subdomain"
curl output
* Host localhost:5222 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
*   Trying [::1]:5222...
* Established connection to localhost (::1 port 5222) from ::1 port 25340
* using HTTP/1.x
> OPTIONS /wildcard HTTP/1.1
> Host: localhost:5222
> User-Agent: curl/8.16.0
> Accept: */*
> Origin: https://test.example.org
> Access-Control-Request-Method: GET
> Access-Control-Request-Headers: authorization,content-type
>
* Request completely sent off
< HTTP/1.1 204 No Content
< Date: Tue, 03 Mar 2026 08:50:03 GMT
< Server: Kestrel
< Access-Control-Allow-Credentials: true
< Access-Control-Allow-Headers: authorization,content-type
< Access-Control-Allow-Methods: GET
< Access-Control-Allow-Origin: https://test.example.org
< Vary: Origin
<
* Connection #0 to host localhost:5222 left intact
* Reusing existing http: connection with host localhost
> OPTIONS /subdomain HTTP/1.1
> Host: localhost:5222
> User-Agent: curl/8.16.0
> Accept: */*
> Origin: https://test.example.org
> Access-Control-Request-Method: GET
> Access-Control-Request-Headers: authorization,content-type
>
< HTTP/1.1 204 No Content
< Date: Tue, 03 Mar 2026 08:50:03 GMT
< Server: Kestrel
<
* Connection #0 to host localhost:5222 left intact

Exceptions (if any)

No response

.NET Version

10.0.102

Anything else?

ASP.NET Core version: whatever is included by default in the template: Microsoft.NET.Sdk.Web
IDE: Visual Studio 2026

dotnet info
.NET SDK:
 Version:           10.0.102
 Commit:            4452502459
 Workload version:  10.0.100-manifests.6d969a7e
 MSBuild version:   18.0.7+445250245

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.26100
 OS Platform: Windows
 RID:         win-x64
 Base Path:   C:\Program Files\dotnet\sdk\10.0.102\

.NET workloads installed:
 [maui-windows]
   Installation Source: VS 18.2.11415.280
   Manifest Version:    10.0.1/10.0.100
   Manifest Path:       C:\Program Files\dotnet\sdk-manifests\10.0.100\microsoft.net.sdk.maui\10.0.1\WorkloadManifest.json
   Install Type:              Msi

 [maccatalyst]
   Installation Source: VS 18.2.11415.280
   Manifest Version:    26.1.10502/10.0.100
   Manifest Path:       C:\Program Files\dotnet\sdk-manifests\10.0.100\microsoft.net.sdk.maccatalyst\26.1.10502\WorkloadManifest.json
   Install Type:              Msi

 [ios]
   Installation Source: VS 18.2.11415.280
   Manifest Version:    26.1.10502/10.0.100
   Manifest Path:       C:\Program Files\dotnet\sdk-manifests\10.0.100\microsoft.net.sdk.ios\26.1.10502\WorkloadManifest.json
   Install Type:              Msi

 [android]
   Installation Source: VS 18.2.11415.280
   Manifest Version:    36.1.2/10.0.100
   Manifest Path:       C:\Program Files\dotnet\sdk-manifests\10.0.100\microsoft.net.sdk.android\36.1.2\WorkloadManifest.json
   Install Type:              Msi

Configured to use workload sets when installing new manifests.
No workload sets are installed. Run "dotnet workload restore" to install a workload set.

Host:
  Version:      10.0.2
  Architecture: x64
  Commit:       4452502459

.NET SDKs installed:
  10.0.102 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 8.0.23 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 9.0.12 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 10.0.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 6.0.36 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 8.0.23 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 9.0.12 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 10.0.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 6.0.36 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 8.0.23 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 9.0.12 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 10.0.2 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

Other architectures found:
  x86   [C:\Program Files (x86)\dotnet]
    registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x86\InstallLocation]

Environment variables:
  Not set

global.json file:
  Not found

Learn more:
  https://aka.ms/dotnet/info

Download .NET:
  https://aka.ms/dotnet/download

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-middlewareIncludes: URL rewrite, redirect, response cache/compression, session, and other general middlewaresfeature-corsThis issue is related to CORS

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions