You may have heard about a change in Business Central v25 regarding validating remote certificates when calling an external web service. If this is new to you, then please read this blog post from Stefano Demiliani: https://demiliani.com/2024/09/23/dynamics-365-business-central-httpclient-and-remote-certificate-validation-future-changes/
Great, now we are all on the same page: validation of remote certificates was enabled for on-prem environments and disabled for SaaS environments. Starting with v25, it was also enabled for SaaS environments. This is considered more secure because who wants to call a web service that uses an untrusted SSL certificate, right? Discussion closed.
Wait, not so fast… Sometimes, untrusted SSL certificates are acceptable or even the only option.
To begin with, what are untrusted certificates? Obviously, certificates with an incorrect name that does not represent the endpoint’s name are not to be trusted, as are certificates that have expired and have not been replaced by a renewed one. These situations are not acceptable and too suspicious. You don’t want to share any data with those endpoints.
However, there are more cases in which a certificate is considered untrusted. For example, if it is not issued by a recognized certification authority, it is also considered untrustworthy. This is the case with self-signed certificates in the first place. This is used in many development scenarios. Many governments use their own certification authority to issue new certificates for their endpoints (e.g., for reporting taxes). Every Windows machine has a list of trusted root certification authorities, like DigiCert, COMODO, GlobalSign, Go Daddy, Microsoft, VeriSign, etc. Any certificate issued by one of these trusted certification authorities is automatically accepted (if it has not expired and has the correct name). This means that certificates issued by governments using their own certification authority will not be accepted unless the root certificate has been added to the trusted store. We can do that for on-prem environments but not for the Business Central SaaS environment.
So here we are: the change in v25 to only accept trusted certificates breaks any integration using a self-signed certificate (self-hosted web services or development scenarios) or a certificate issued by a certification authority that is not on the trusted list (integrations with government APIs). This breaking change was not communicated a year in advance, as it should have been.
Here is a basic code example to test this behavior.
procedure TestSelfSignedCertificate() begin GetURLData('https://self-signed.badssl.com/'); end; procedure TestExpiredCertificate() begin GetURLData('https://expired.badssl.com/'); end; procedure TestUntrustedRootCertificate() begin GetURLData('https://untrusted-root.badssl.com/'); end; procedure TestWrongHostCertificate() begin GetURLData('https://wrong.host.badssl.com/'); end; procedure GetURLData(URLValue: Text) var HttpClient: HttpClient; HttpResponseMessage: HttpResponseMessage; Response: Text; begin HttpClient.Get(URLValue, HttpResponseMessage); HttpResponseMessage.Content.ReadAs(Response); Message('%1', Response); end;
This issue has been shared with Microsoft:
And it seems Microsoft has listened. I’ve not seen any official communication, but the change has been rolled back, and all Business Central SaaS environments are back to the previous behavior. Not only v25.1 environments but also v25.0 environments have been updated. I have tested sandboxes and production environments, and it works in both.
I did some desktop research and found that a server setting controls this behavior. This applies to both online and on-prem environments.
The server setting is ServicesCertificateValidationEnabled. If this is set to true, the validation on certificates is run. If set to false, it skips the validation. For on-prem, you can use this PowerShell code to disable the certificate validation (it also works on Docker environments). A server restart is required to activate the new setting.
Set-NAVServerConfiguration -ServerInstance BC -KeyName ServicesCertificateValidationEnabled -KeyValue true Restart-NAVServerInstance -ServerInstance BC
So, problem solved? Well, not really. We are now back to the situation in which SSL certificates are not verified on the BC SaaS platform. I doubt if Microsoft will let that situation continue forever. Current integrations are safe for now, but I expect Microsoft to apply the zero-trust policy in the near future. I’m not revealing any information here; it’s just my gut feeling that they won’t accept the current situation because it makes the SaaS platform vulnerable.
In my opinion, the best short-term option would be to block at least expired and revoked SSL certificates and name mismatches. That would at least solve part of the problem, and it is not very difficult to implement because it doesn’t require any change in AL code.
For self-signed certificates and certificates issued by unknown root certification authorities, such as governments, it would be optimal if we could provide the expected certificate (or its thumbprint) in AL code before making the request. Alternatively, Microsoft could choose to collect more root certificates to be accepted on the BC platform and block self-signed certificates. That would definitely be the most secure option because then Microsoft is in control. But that would add quite some extra administration, so I guess it’s all about balancing between risk and effort.
To be continued, I guess!
Original Post https://www.kauffmann.nl/2024/12/02/httpclient-and-certificate-validation-in-business-central-v25/