diff --git a/code-reviews/Server/findings.md b/code-reviews/Server/findings.md index 6b924f7..34a0209 100644 --- a/code-reviews/Server/findings.md +++ b/code-reviews/Server/findings.md @@ -158,13 +158,13 @@ | Severity | Medium | | Category | Security | | Location | `src/Server/ZB.MOM.WW.OtOpcUa.Server/OpcUa/OpcUaServerOptions.cs:59`, `src/Server/ZB.MOM.WW.OtOpcUa.Server/OpcUa/OpcUaApplicationHost.cs:284-291` | -| Status | Open | +| Status | Resolved | **Description:** `AutoAcceptUntrustedClientCertificates` defaults to `true` (`Program.cs` reads `?? true`). `BuildConfiguration` wires a handler that accepts any client cert failing with `BadCertificateUntrusted`. A deployment that forgets to flip the flag accepts every untrusted client cert, defeating the PKI trust list. With the always-present `None` policy, the default posture is fully open. **Recommendation:** Default `AutoAcceptUntrustedClientCertificates` to `false`; keep auto-accept as opt-in dev convenience. `docs/security.md` already shows `false` — align code to doc. -**Resolution:** _(open)_ +**Resolution:** Resolved 2026-05-22 — `OpcUaServerOptions.AutoAcceptUntrustedClientCertificates` property initialiser changed from `true` to `false` (secure by default, aligning with `docs/security.md`); `Program.cs` config fallback changed from `?? true` to `?? false`. ### Server-011 | Field | Value | diff --git a/src/Server/ZB.MOM.WW.OtOpcUa.Server/OpcUa/OpcUaServerOptions.cs b/src/Server/ZB.MOM.WW.OtOpcUa.Server/OpcUa/OpcUaServerOptions.cs index 3ebc1b0..cd69a77 100644 --- a/src/Server/ZB.MOM.WW.OtOpcUa.Server/OpcUa/OpcUaServerOptions.cs +++ b/src/Server/ZB.MOM.WW.OtOpcUa.Server/OpcUa/OpcUaServerOptions.cs @@ -52,11 +52,12 @@ public sealed class OpcUaServerOptions "OtOpcUa", "pki"); /// - /// When true, the stack auto-trusts client certs on first connect. Dev-default = true, - /// production deployments should flip this to false and manually trust clients via the - /// Admin UI. + /// When true, the stack auto-trusts client certs on first connect and bypasses PKI + /// trust-list enforcement. Defaults to false (secure by default) — set to + /// true only in dev / test environments. Production deployments should manually + /// trust clients via the Admin UI (Server-010). /// - public bool AutoAcceptUntrustedClientCertificates { get; init; } = true; + public bool AutoAcceptUntrustedClientCertificates { get; init; } = false; /// /// Whether to start the Phase 6.1 Stream C /healthz + /readyz HTTP listener. diff --git a/src/Server/ZB.MOM.WW.OtOpcUa.Server/Program.cs b/src/Server/ZB.MOM.WW.OtOpcUa.Server/Program.cs index 7943a0d..3fdae12 100644 --- a/src/Server/ZB.MOM.WW.OtOpcUa.Server/Program.cs +++ b/src/Server/ZB.MOM.WW.OtOpcUa.Server/Program.cs @@ -96,7 +96,7 @@ var opcUaOptions = new OpcUaServerOptions ApplicationUri = opcUaSection.GetValue("ApplicationUri") ?? "urn:OtOpcUa:Server", PkiStoreRoot = opcUaSection.GetValue("PkiStoreRoot") ?? Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "OtOpcUa", "pki"), - AutoAcceptUntrustedClientCertificates = opcUaSection.GetValue("AutoAcceptUntrustedClientCertificates") ?? true, + AutoAcceptUntrustedClientCertificates = opcUaSection.GetValue("AutoAcceptUntrustedClientCertificates") ?? false, // Server-010: secure by default SecurityProfile = Enum.TryParse(opcUaSection.GetValue("SecurityProfile"), true, out var p) ? p : OpcUaSecurityProfile.None, Ldap = ldapOptions,