OrchardCore icon indicating copy to clipboard operation
OrchardCore copied to clipboard

Invalid CORS config can make the site unusable

Open rjpowers10 opened this issue 2 months ago • 5 comments

Describe the bug

If you try to configure the CORS feature with a wildcard origin (an asterisk) and credentials, you create an invalid config that throws an exception on subsequent page loads. At this point I have to manually run SQL to fix it so I can get back into the site.

To be clear, this is user error for entering something that is invalid. The problem is I can't get back into the site to correct the error.

Orchard Core version

2.2.1

To Reproduce

  1. Create a new OC site with the blog recipe
  2. Enable the CORS feature
  3. Add a new CORS policy
  4. Check the "set as default policy" box
  5. Check the "allow credentials" box
  6. Uncheck the "Allow any origin" box
  7. In the "allowed origins" input, enter an asterisk and click the "Add Origin" button
  8. Click the "Save" button

Expected behavior

OC validation will correctly prevent me from checking both "allow credentials" and "allow any origin". I expect it to also prevent me from checking "allow credentials" and entering an asterisk as an allowed origin.

Logs and screenshots

If you try to view a page you get the following exception.

System.InvalidOperationException: The CORS protocol does not allow specifying a wildcard (any) origin and credentials at the same time. Configure the CORS policy by listing individual origins if credentials needs to be supported.
   at Microsoft.AspNetCore.Cors.Infrastructure.CorsPolicyBuilder.Build()
   at Microsoft.AspNetCore.Cors.Infrastructure.CorsOptions.AddPolicy(String name, Action`1 configurePolicy)
   at OrchardCore.Cors.Services.CorsOptionsConfiguration.Configure(CorsOptions options) in C:\Users\ryan.powers\source\static\OrchardCore-2.2.1\src\OrchardCore.Modules\OrchardCore.Cors\Services\CorsOptionsConfiguration.cs:line 34
   at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
   at Microsoft.Extensions.Options.UnnamedOptionsManager`1.get_Value()
   at Microsoft.AspNetCore.Cors.Infrastructure.CorsService..ctor(IOptions`1 options, ILoggerFactory loggerFactory)
   at InvokeStub_CorsService..ctor(Object, Span`1)
   at System.Reflection.MethodBaseInvoker.InvokeWithFewArgs(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass2_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(ServiceIdentifier serviceIdentifier, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType)
   at Microsoft.Extensions.Internal.ActivatorUtilities.ConstructorMatcher.CreateInstance(IServiceProvider provider)
   at Microsoft.Extensions.Internal.ActivatorUtilities.CreateInstance(IServiceProvider provider, Type instanceType, Object[] parameters)
   at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.ReflectionMiddlewareBinder.CreateMiddleware(RequestDelegate next)
   at Microsoft.AspNetCore.Builder.ApplicationBuilder.Build()
   at OrchardCore.Modules.ShellPipelineExtensions.BuildPipelineInternalAsync(ShellContext context) in C:\Users\ryan.powers\source\static\OrchardCore-2.2.1\src\OrchardCore\OrchardCore\Modules\Extensions\ShellPipelineExtensions.cs:line 60
   at OrchardCore.Modules.ShellPipelineExtensions.BuildPipelineAsync(ShellContext context) in C:\Users\ryan.powers\source\static\OrchardCore-2.2.1\src\OrchardCore\OrchardCore\Modules\Extensions\ShellPipelineExtensions.cs:line 32
   at OrchardCore.Modules.ModularTenantRouterMiddleware.Invoke(HttpContext httpContext) in C:\Users\ryan.powers\source\static\OrchardCore-2.2.1\src\OrchardCore\OrchardCore\Modules\ModularTenantRouterMiddleware.cs:line 42
   at OrchardCore.Modules.ModularTenantContainerMiddleware.<>c__DisplayClass4_0.<<Invoke>b__0>d.MoveNext() in C:\Users\ryan.powers\source\static\OrchardCore-2.2.1\src\OrchardCore\OrchardCore\Modules\ModularTenantContainerMiddleware.cs:line 60
--- End of stack trace from previous location ---
   at OrchardCore.Environment.Shell.Scope.ShellScope.UsingAsync(Func`2 execute, Boolean activateShell) in C:\Users\ryan.powers\source\static\OrchardCore-2.2.1\src\OrchardCore\OrchardCore.Abstractions\Shell\Scope\ShellScope.cs:line 286
   at OrchardCore.Environment.Shell.Scope.ShellScope.UsingAsync(Func`2 execute, Boolean activateShell) in C:\Users\ryan.powers\source\static\OrchardCore-2.2.1\src\OrchardCore\OrchardCore.Abstractions\Shell\Scope\ShellScope.cs:line 291
   at OrchardCore.Environment.Shell.Scope.ShellScope.UsingAsync(Func`2 execute, Boolean activateShell) in C:\Users\ryan.powers\source\static\OrchardCore-2.2.1\src\OrchardCore\OrchardCore.Abstractions\Shell\Scope\ShellScope.cs:line 296
   at OrchardCore.Environment.Shell.Scope.ShellScope.UsingAsync(Func`2 execute, Boolean activateShell) in C:\Users\ryan.powers\source\static\OrchardCore-2.2.1\src\OrchardCore\OrchardCore.Abstractions\Shell\Scope\ShellScope.cs:line 301
   at OrchardCore.Environment.Shell.Scope.ShellScope.UsingAsync(Func`2 execute, Boolean activateShell) in C:\Users\ryan.powers\source\static\OrchardCore-2.2.1\src\OrchardCore\OrchardCore.Abstractions\Shell\Scope\ShellScope.cs:line 302
   at OrchardCore.Modules.ModularTenantContainerMiddleware.Invoke(HttpContext httpContext) in C:\Users\ryan.powers\source\static\OrchardCore-2.2.1\src\OrchardCore\OrchardCore\Modules\ModularTenantContainerMiddleware.cs:line 58
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

rjpowers10 avatar Nov 14 '25 21:11 rjpowers10

To clarify, you think only additional validation would be sufficient to fix this, right? So, not something akin to the Windows "Do you want to keep these display settings? Answer within 15 seconds or it reverts." feature.

Piedone avatar Nov 15 '25 15:11 Piedone

Luckily, I'm checking this right now to verify the bug

hishamco avatar Nov 15 '25 15:11 hishamco

I'm able to reproduce the bug, but * is from any origin, right?

hishamco avatar Nov 15 '25 15:11 hishamco

To clarify, you think only additional validation would be sufficient to fix this, right? So, not something akin to the Windows "Do you want to keep these display settings? Answer within 15 seconds or it reverts." feature.

I think the additional validation would be sufficient in this case. Some sort of revert/recover is an interesting idea, but feels more like a "nice to have maybe someday".

I'm able to reproduce the bug, but * is from any origin, right?

I think the issue is that the checkbox for "allow any origin" and entering * are essentially the same thing but the validation only catches the first case.

rjpowers10 avatar Nov 17 '25 14:11 rjpowers10

We triaged this issue and set the milestone according to the priority we think is appropriate (see the docs on how we triage and prioritize issues).

This indicates when the core team may start working on it. However, if you'd like to contribute, we'd warmly welcome you to do that anytime. See our guide on contributions here.

github-actions[bot] avatar Nov 20 '25 18:11 github-actions[bot]