diff --git a/code-reviews/Admin/findings.md b/code-reviews/Admin/findings.md index 1833584..42c153a 100644 --- a/code-reviews/Admin/findings.md +++ b/code-reviews/Admin/findings.md @@ -108,13 +108,13 @@ | Severity | Medium | | Category | Security | | Location | `Components/Layout/MainLayout.razor:47-49`, `Program.cs:129,131-135` | -| Status | Open | +| Status | Resolved | **Description:** `app.UseAntiforgery()` is enabled, but the Sign-out form (`
diff --git a/src/Server/ZB.MOM.WW.OtOpcUa.Admin/Security/AuthEndpoints.cs b/src/Server/ZB.MOM.WW.OtOpcUa.Admin/Security/AuthEndpoints.cs index 5aae189..31c1397 100644 --- a/src/Server/ZB.MOM.WW.OtOpcUa.Admin/Security/AuthEndpoints.cs +++ b/src/Server/ZB.MOM.WW.OtOpcUa.Admin/Security/AuthEndpoints.cs @@ -21,15 +21,21 @@ public static class AuthEndpoints public static IEndpointRouteBuilder MapAuthEndpoints(this IEndpointRouteBuilder endpoints) { // Anonymous: the login POST is the only way in, so the fallback authorization policy - // (Admin-001) must not gate it. DisableAntiforgery — the static form posts with - // data-enhance="false" and renders no token; the cookie scheme + LDAP bind are the - // gate here. (Admin-006 covers emitting a token for a hardened build.) + // (Admin-001) must not gate it. DisableAntiforgery — the static Login.razor form posts + // with data-enhance="false" and renders no antiforgery token; the cookie scheme + LDAP + // bind are the authentication gate here. Login is not a state-changing operation that + // CSRF can abuse (the attacker cannot know the resulting cookie), so tokenless-login is + // the standard Web pattern. endpoints.MapPost("/auth/login", (Delegate)LoginAsync) .AllowAnonymous() .DisableAntiforgery(); - endpoints.MapPost("/auth/logout", (Delegate)LogoutAsync) - .DisableAntiforgery(); + // Admin-006: the logout form in MainLayout.razor emits