Remove CORS policy for production environments (#588)

This commit is contained in:
Flaminel
2026-04-27 13:13:06 +03:00
committed by GitHub
parent 85de80a463
commit 8ab4a55595
3 changed files with 47 additions and 11 deletions

View File

@@ -80,7 +80,10 @@ public static class ApiDI
// Block non-auth requests until setup is complete
app.UseMiddleware<SetupGuardMiddleware>();
app.UseCors("Any");
if (app.Environment.IsDevelopment())
{
app.UseCors("DevSpa");
}
app.UseRouting();
app.UseAuthentication();

View File

@@ -80,19 +80,21 @@ builder.Services
.PersistKeysToFileSystem(new DirectoryInfo(Path.Combine(ConfigurationPathProvider.GetConfigPath(), "DataProtection-Keys")))
.SetApplicationName("Cleanuparr");
// Add CORS before SignalR
builder.Services.AddCors(options =>
// CORS is needed only for development
if (builder.Environment.IsDevelopment())
{
options.AddPolicy("Any", policy =>
builder.Services.AddCors(options =>
{
policy
// https://github.com/dotnet/aspnetcore/issues/4457#issuecomment-465669576
.SetIsOriginAllowed(_ => true)
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials(); // Required for SignalR auth
options.AddPolicy("DevSpa", policy =>
{
policy
.WithOrigins("http://localhost:4200", "http://127.0.0.1:4200")
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});
});
}
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{

View File

@@ -0,0 +1,31 @@
import { test, expect } from '@playwright/test';
import { TEST_CONFIG } from './helpers/test-config';
// Regression for GHSA-rwpc-36mg-fpvf
test.describe.serial('GHSA-rwpc-36mg-fpvf regression', () => {
const ATTACKER_ORIGIN = 'https://attacker.example';
test('does not reflect a malicious Origin in Access-Control-Allow-Origin on actual requests', async ({ request }) => {
const res = await request.get(`${TEST_CONFIG.appUrl}/api/auth/status`, {
headers: { Origin: ATTACKER_ORIGIN },
});
expect(res.status()).toBe(200);
const acao = res.headers()['access-control-allow-origin'];
expect(acao).toBeUndefined();
});
test('does not reflect on CORS preflight either', async ({ request }) => {
const res = await request.fetch(`${TEST_CONFIG.appUrl}/api/auth/status`, {
method: 'OPTIONS',
headers: {
Origin: ATTACKER_ORIGIN,
'Access-Control-Request-Method': 'GET',
},
});
const acao = res.headers()['access-control-allow-origin'];
expect(acao).toBeUndefined();
});
});