From 74b852716c6f05d63c4b6260206c1e6f345608ef Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Mon, 10 Aug 2026 06:59:34 -0400 Subject: [PATCH] fix(mqtt-transport): warn when the untrusted-cert hatch voids a pinned CA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Driver.Mqtt.Transport-001 (Medium, Security). allowUntrustedServerCertificate and caCertificatePath are independent settings, and when both are set the hatch wins SILENTLY: ConfigureTls installs the accept-everything validator and returns before the pin is consulted. The combination is not exotic — the hatch is what an operator turns on while standing a broker up and the pin is what they add afterwards — and the failure is silent in the direction that matters: the config reads as pinned, and nothing validates anything. Both knobs are explicit, so the flag stays authoritative (overriding it would break a deployment that genuinely wants the hatch, and refusing to build would fault a driver over a config we have been accepting). Saying so once, at the seam that resolves the conflict, is the proportionate answer. No behaviour change; the factory's optional ILogger already exists for this class of deferred diagnostic and never formats credentials. --- .../MqttClientOptionsFactory.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Transport/MqttClientOptionsFactory.cs b/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Transport/MqttClientOptionsFactory.cs index 8b0dcd69..0f7e4333 100644 --- a/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Transport/MqttClientOptionsFactory.cs +++ b/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Transport/MqttClientOptionsFactory.cs @@ -119,6 +119,21 @@ public static class MqttClientOptionsFactory if (options.AllowUntrustedServerCertificate) { + // A configured CA pin is DEAD in this branch — every certificate is accepted, pinned chain + // or not. Silence here reads to an operator as "the pin is in force", which is the one + // belief this combination must never leave them holding: the pin is what they set to make a + // MITM fail closed, and the escape hatch is what makes it fail open. Warn, do not + // second-guess — the explicit flag stays authoritative, so a deployment that genuinely wants + // the hatch keeps working and merely says so in its log. + if (!string.IsNullOrWhiteSpace(options.CaCertificatePath)) + { + logger?.LogWarning( + "MQTT: allowUntrustedServerCertificate is on, so the pinned CA '{CaCertificatePath}' is NOT " + + "being enforced — ANY broker certificate is accepted. Clear the flag to make the pin " + + "effective.", + options.CaCertificatePath); + } + // Dev / on-prem escape hatch, off unless explicitly enabled — mirrors the // ServerHistorian TLS knobs. This is the ONLY branch that accepts a bad certificate. tls.WithAllowUntrustedCertificates(true)