Invalid CORS config can make the site unusable
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
- Create a new OC site with the blog recipe
- Enable the CORS feature
- Add a new CORS policy
- Check the "set as default policy" box
- Check the "allow credentials" box
- Uncheck the "Allow any origin" box
- In the "allowed origins" input, enter an asterisk and click the "Add Origin" button
- 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)
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.
Luckily, I'm checking this right now to verify the bug
I'm able to reproduce the bug, but * is from any origin, right?
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.
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.