From c8cf5c8032a61411fd8bf29401cf59f95ce8dbbe Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Thu, 20 Aug 2026 10:43:49 -0400 Subject: [PATCH] test(host): the R3-01 falsifiability control asserts the cookie-challenge signature (a bare Exception was satisfiable by an anonymised endpoint too); docs wording --- docs/security.md | 4 ++-- .../MeshGrpcAuthStackTests.cs | 8 +++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/security.md b/docs/security.md index bd44294b..d313d65e 100644 --- a/docs/security.md +++ b/docs/security.md @@ -890,7 +890,7 @@ The fifth, `MapZbLocalDbSync()`, returns `IEndpointRouteBuilder` rather than an `app.MapGroup(string.Empty).AllowAnonymous().MapZbLocalDbSync()`, which carries the convention without changing the wire route pattern. -**Two standing guards**, both in `tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests/`, so a future map +**Three standing guards**, all in `tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests/`, so a future map cannot silently reopen this: - `MeshGrpcAnonymousMetadataTests` — an endpoint-metadata census that calls the SAME @@ -899,7 +899,7 @@ cannot silently reopen this: and a scope check that the opt-out never leaks onto an unrelated endpoint. - `MeshGrpcMapConventionTests` — a `Program.cs` source scan asserting zero direct `MapGrpcService( + // Review (R3-01): asserting a bare Exception was vacuous — an anonymised endpoint ALSO throws + // here (handler deps are not wired in this fixture => RpcException Unknown). Only the + // cookie-challenge signature discriminates: the FallbackPolicy's 302 to /login is a + // non-gRPC response, surfaced by grpc-dotnet as Internal + PROTOCOL_ERROR. + var ex = await Should.ThrowAsync( () => call.ResponseStream.MoveNext(TestContext.Current.CancellationToken)); + ex.StatusCode.ShouldBe(StatusCode.Internal); + ex.Status.Detail.ShouldContain("PROTOCOL_ERROR"); } // ---------------------------------------------------------------------------------------