KB4344167 security update breaks TLS Code
Asked Answered
R

2

7

Hopefully someone can help with this problem. Recently our machines were updated with KB4344167 which includes security updates for .NET 4.7.1. Unfortunately this update has broken our code for a Webrequest. When we run the code below we get this error:

The request was aborted: Could not create SSL/TLS secure channel.

// Create a request for the URL.        
WebRequest request = WebRequest.Create(url);
//specify to use TLS 1.2 as default connection
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
request.Timeout = int.Parse(configmanager.GetSetting("Webtimeout"));
// Set proxy
request.Proxy = WebRequest.DefaultWebProxy;
request.Proxy.Credentials = CredentialCache.DefaultCredentials;
// Define a cache policy for this request only. 
HttpRequestCachePolicy noCachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore);
request.CachePolicy = noCachePolicy;
ServicePointManager.ServerCertificateValidationCallback = (s, cert, chain, ssl) => true;
// Get the response.
HttpWebResponse response = (HttpWebResponse)request.GetResponse();

When the security update is uninstalled from the machine the code executes fine. Are we missing something in the code above? Thats about the only thing I can think of.

Any help is greatly appreciated!

Recoverable answered 12/9, 2018 at 13:53 Comment(13)
TLS 1.1 has been depreciated because of security vulnerabilities, have you tried removing that flag from the security protocol?Greyhound
See also learn.microsoft.com/en-us/dotnet/framework/network-programming/…Embolectomy
Moving forward, you probably want to make it ServicePointManager.SecurityProtocol = SecurityProtocol.SystemDefault (since 4.7), so you don't have to roll out new code as versions are introduced and deprecated. This may still cause connectivity problems to hosts if they're not up to date, but that's a problem code alone won't solve.Pedicure
So far as I'm aware, ServicePointManager.SecurityProtocol is accessed/copied during the Create() call. Changing it afterwards should have no noticeable effect (either before or after applying any fix)Lanitalank
We had to add the ServicePointManager.SecurityProtocol line to address our servers being updated from TLS 1.1 to 1.2 and its been working up to this August security update.Recoverable
Damien's remark is apt: with the line in place where it is, only the second request in the application should pick up the setting; the web request created just before the change will copy whatever the existing setting was. This may or may not be noticeable in practice, depending on how your application actually issues requests, but it's still not what you want in any case. It may not be the cause of this issue, but it's confusing nonetheless.Pedicure
But that line still allows TLS 1.1 and TLS 1.0, and as I say, so far as I'm aware, it's not effective. I'm strongly suspecting (from what you've said in some comments) that you've still actually been connecting with a lower TLS level and the update is now preventing that. I.e. it was never working how you thought it was.Lanitalank
That code should be using TLS 1.2 which should be fine. I use similar code internally without an issue. Something in the request pipeline must not support TLS 1.2 and is lowering the protocol.Borries
I'd suggest consulting this question which shows various ways of inspecting your traffic to see what TLS version gets negotiated (both without the patch to see what is settled and with the patch to see where it falls over)Lanitalank
I really appreciate all the comments. We are making some changes to the code and testing.Recoverable
Just to clarify, the code above works with TLS 1.2 on our server as long as KB4344167 isn't installed on the users machine. I moved the ServicePointManger line to about the Create and it continues to work. If I change the ServicePointManager to use SecurityProtocolType.SystemDefault the code fails without KB4344167 installed on the machine.Recoverable
What version of TLS is attempted with .SystemDefault or the KB installed? It may be that (for example) 1.3 is negotiated with the new settings, but fails on a mismatch in cipher suites. (Unfortunately TLS libs are notorious for boiling all failures down to unhelpful "it didn't work" messages.) Beyond poring over Wireshark traces, you can enable or increase the Schannel logging and see what ends up in the event log.Pedicure
For us apart from adding the following emtry in config file, it needed .net framework 4.6.2 <runtime> <AppContextSwitchOverrides value="Switch.System.Net.DontEnableSchUseStrongCrypto=false" /> </runtime>Adames
R
1

@Damien_The_Unbeliever had the correct answer. Ultimately the problem was the order of the ServicePointManager and the Webrequest.Create. Reversing those lines, so the ServicePointManager is defined before the Webrequest.Create fixed the issue. I still don't know why adding the ServicePointManager after the Create fixed our original issue when our server moved to TLS 1.2, but we're not going to worry about that now.

Recoverable answered 12/9, 2018 at 19:27 Comment(0)
T
0

I ran into something similar. It appears MS may have broken something in their attempt to only enable TLS 1.2. https://support.microsoft.com/en-us/help/4458166/applications-that-rely-on-tls-1-2-strong-encryption-experience-connect

So far, I've tried adding the suggested config to the app.config and it worked like a charm. No more SSL/TLS errors.

<runtime> <AppContextSwitchOverrides value="Switch.System.Net.DontEnableSchUseStrongCrypto=false" /> </runtime>

NOTE: we found this on servers that are selectively patched, i.e. they don't yet have the MS fix. Our development machines never saw the problem.

Tessy answered 24/9, 2018 at 19:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.