feat(stability): unify readiness and recovery
CI - Build & Test / Backend (.NET) (push) Successful in 45s
CI - Build & Test / Backend integration (PostgreSQL/Toxiproxy) (push) Failing after 1m0s
CI - Build & Test / Frontend (Vue/TS) (push) Successful in 2m49s
CI - Build & Test / Security Check (push) Successful in 7s
CI - Build & Test / Deploy Nexus (push) Has been skipped
CI - Build & Test / Backend (.NET) (push) Successful in 45s
CI - Build & Test / Backend integration (PostgreSQL/Toxiproxy) (push) Failing after 1m0s
CI - Build & Test / Frontend (Vue/TS) (push) Successful in 2m49s
CI - Build & Test / Security Check (push) Successful in 7s
CI - Build & Test / Deploy Nexus (push) Has been skipped
This commit is contained in:
@@ -10,6 +10,7 @@ using Microsoft.Extensions.Options;
|
||||
using Nexus.Api.Controllers;
|
||||
using Nexus.Api.Extensions;
|
||||
using Nexus.Api.Middleware;
|
||||
using Nexus.Api.Security;
|
||||
using Nexus.Api.Services;
|
||||
using Xunit;
|
||||
|
||||
@@ -90,7 +91,6 @@ public sealed class SecurityBoundaryTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(nameof(AuthController.GetCsrfToken))]
|
||||
[InlineData(nameof(AuthController.Login))]
|
||||
[InlineData(nameof(AuthController.Refresh))]
|
||||
[InlineData(nameof(AuthController.Logout))]
|
||||
@@ -104,6 +104,7 @@ public sealed class SecurityBoundaryTests
|
||||
|
||||
[Theory]
|
||||
[InlineData(nameof(HealthController.Live))]
|
||||
[InlineData(nameof(HealthController.Ready))]
|
||||
[InlineData(nameof(HealthController.Get))]
|
||||
public void PublicHealthEndpoints_AreExplicitlyAnonymous(string methodName)
|
||||
{
|
||||
@@ -123,6 +124,34 @@ public sealed class SecurityBoundaryTests
|
||||
Assert.Empty(method!.GetCustomAttributes(typeof(AllowAnonymousAttribute), inherit: true));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CookieBackedAuth_AllowsSameOriginBrowserRequests()
|
||||
{
|
||||
var context = new DefaultHttpContext();
|
||||
context.Request.Scheme = "https";
|
||||
context.Request.Host = new HostString("nexus.noveria.net");
|
||||
context.Request.Headers.Origin = "https://nexus.noveria.net";
|
||||
context.Request.Headers["Sec-Fetch-Site"] = "same-origin";
|
||||
|
||||
Assert.True(BrowserRequestOriginGuard.IsAllowed(context.Request));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("https://attacker.invalid", "cross-site")]
|
||||
[InlineData("https://attacker.invalid", "")]
|
||||
[InlineData("not-an-origin", "same-origin")]
|
||||
public void CookieBackedAuth_RejectsExplicitCrossSiteRequests(string origin, string fetchSite)
|
||||
{
|
||||
var context = new DefaultHttpContext();
|
||||
context.Request.Scheme = "https";
|
||||
context.Request.Host = new HostString("nexus.noveria.net");
|
||||
context.Request.Headers.Origin = origin;
|
||||
if (fetchSite.Length > 0)
|
||||
context.Request.Headers["Sec-Fetch-Site"] = fetchSite;
|
||||
|
||||
Assert.False(BrowserRequestOriginGuard.IsAllowed(context.Request));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AgentIdentityHeader_IsRejectedWithoutVerifiedAuthentication()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user