Applies To.NET Framework 4.6.1 .NET Framework 4.6.2 .NET Framework 3.5.1

Summary

An information disclosure vulnerability exists in the Transport Layer Security protocol and the Secure Sockets Layer protocol (TLS/SSL) as implemented in the encryption component of the Microsoft .NET Framework. An attacker who successfully exploited this vulnerability could decrypt encrypted TLS/SSL traffic.To exploit the vulnerability, an attacker would first have to inject nonencrypted data into the security channel and then perform a man-in-the-middle (MiTM) attack between the targeted client and a legitimate server. This update addresses the vulnerability by modifying the way that the .NET encryption component sends and receives encrypted network packets.This vulnerability is fixed as part of Microsoft Security Bulletin MS16-065. This update changes the way that the .NET Framework encryption component sends and receives encrypted network packets.

The following table contains links to the standard entry for each vulnerability in the Common Vulnerabilities and Exposures list.

Vulnerability title

CVE number

Publicly disclosed

Exploited

TLS/SSL Spoofing Vulnerability

CVE-2016-0149

Yes

No

Vulnerability Resolution

The change introduced in Microsoft Security Bulletin MS16-065 causes the first TLS record after the handshake to be split. This causes the SslStream, WebRequest (HttpWebRequest, FtpWebRequest), SmtpClient, and HttpClient (where based on HttpWebRequest) streams to return a single byte for the first read, immediately followed by the rest (n-1) bytes in successive reads. This behavior change only occurs for applications that use TLS 1.0 + Cipher Block Chaining, but not when they use TLS 1.1 or TLS 1.2.Note As a prerequisite, you must install Microsoft Security Bulletin MS12-006 to enable this update.This change may cause some applications that are based on the .NET Framework to break. This article describes two approaches you can use to update your application to work correctly after you apply Microsoft Security Bulletin MS16-065.

Mitigations for compatibility issues

Option 1: Switch to the TLS 1.2 protocol

This option makes the application use the TLS 1.2 protocol by either modifying the registry or programmatically configuring the protocol version.

  • Modify the registryImportant Follow the steps in this section carefully. Serious problems might occur if you modify the registry incorrectly. Before you modify it, back up the registry for restoration in case problems occur.The .NET Framework 4.0 and the .NET Framework 4.5.x applications that are running on the .NET Framework 4.5 and later versions can switch the default protocol to TLS 1.2, TLS 1.1, and TLS 1.0 by enabling the SchUseStrongCrypto registry key. This registry key is discussed in the Suggested Actions section of the Microsoft Security Advisory 2960358 topic on the Microsoft TechNet website.Important This registry change will only work if the following conditions are true:

    • Applications that use ServicePointManager-based APIs are not setting the ServicePointManager.SecurityProtocol value explicitly. Examples of such classes include System.Net.Http.HttpClient, System.Net.FtpWebRequest, System.Net.HttpWebRequest, and System.Net.Mail.SmtpClient. Setting the ServicePointManager.SecurityProtocol in code takes precedence over the registry.

    • Applications are using the SslStream AuthenticateAsClient(String) overload.

  • Programmatically configure the protocol versionThe .NET Framework 4.0 and 4.5 applications that are running on the .NET Framework 4.5 and later versions and that use the SslStream AuthenticateAsClient(String, X509CertificateCollection, SslProtocols, Boolean) overload must be recompiled, specifying SslProtocols.Tls12, SslProtocols.Tls11, and SslProtocols.Tls as the third parameter. For a complete description of how to use the SslStream class, see the SslStream Class topic on the Microsoft Developer (MSDN) website.Note The .NET Framework 4.6 and later versions use TLS 1.2, TLS 1.1, and TLS 1.0 as the protocol defaults. This is discussed in the Microsoft Security Advisory 2960358 topic on the Microsoft TechNet website.

Option 2: Handle split packets

This update causes a single record to be split into multiple records. Therefore, if an application is expecting the complete record to be available in a single Read call, such applications may break. To make sure that the application behaves correctly, verify that the application handles split packets by performing the Stream.Read call correctly. You can use the sample code available here as a reference for how to fix the application to correctly perform the Read call.For a sample HTTP request that shows the difference in behavior before (with the mitigation) and after (without the mitigation) updates 3147461 and 3147458 were installed, see the "More Information" section.For a complete example of the Stream.Read method, see the Stream.Read Method (Byte[], Int32, Int32) topic on the Microsoft Developer (MSDN) website.

Workarounds to Application Compatibility Issues

Warning These workarounds may make a computer or a network more vulnerable to attack by malicious users or by malicious software such as viruses. We do not recommend these workarounds but are providing this information so that you can implement these workarounds at your own discretion. Use these workarounds at your own risk.

Method 1: Update registry keys (available for all versions of the .NET Framework)

Disable the SCH_SEND_AUX_RECORD structure (globally) Disable SCH_SEND_AUX_RECORD structure for individual applications

Disable SCH_SEND_AUX_RECORD structure (globally)

For all applications, add the following registry subkey:

Registry location:HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\<version_number>DWORD name: SchSendAuxRecordValue data: 0Note The <version_number> placeholder is either v4.0.30319 or v2.0.50727, depending on the version.For 32-bit applications that run on 64-bit computers, also add the following registry subkey:

Registry location:HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\.NETFramework\<version_number>DWORD name: SchSendAuxRecordValue data: 0Note The <version_number> placeholder is either v4.0.30319 or v2.0.50727, depending on the version.

Workaround

To temporarily disable the secure mode described in this article, click the appropriate link to download a .reg file, and then double-click the downloaded .reg file to make the registry changes.For applications targeting the Microsoft .NET Framework 3.5:

Download Download the ManualOptOutSchSendAuxRecord20.reg file now. For applications targeting the Microsoft .NET Framework 4.0 and later versions:

Download Download the ManualOptOutSchSendAuxRecord40.reg file now. To re-enable the secure mode described in this article, click the appropriate link to download a .reg file, and then double-click the downloaded .reg file to make the registry changes.For applications targeting Microsoft .NET Framework 3.5:

Download Download the ManualOptInSchSendAuxRecord20.reg file now. For applications targeting the Microsoft .NET Framework 4.0 and later versions:

Download Download the ManualOptInSchSendAuxRecord40.reg file now. For more information about how to download Microsoft support files, click the following article number to view the article in the Microsoft Knowledge Base:

119591 How to obtain Microsoft support files from online services Microsoft scanned this file for viruses. Microsoft used the most current virus-detection software that was available on the date that the file was posted. The file is stored on security-enhanced servers that help prevent any unauthorized changes to the file.

Disable SCH_SEND_AUX_RECORD structure for individual applications

For all applications, add the following registry subkey:

Registry location:HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\<version_number>\System.Net.ServicePointManager.SchSendAuxRecordDWORD name: Fully qualified path for the application .exe (for example, C:\MyApp\MyApp.exe)Value data: 0Note The <version_number> placeholder is either v4.0.30319 or v2.0.50727, depending on the version.For 32-bit applications that run on 64-bit computers, also add the following registry subkey:

Registry location:HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\.NETFramework\<version_number>\System.Net.ServicePointManager.SchSendAuxRecordDWORD name: Fully qualified path for the application .exe (for example, C:\MyApp\MyApp.exe)Value data: 0 (The only valid value is 0. Any other value will be ignored.) Note The <version_number> placeholder is either v4.0.30319 or v2.0.50727, depending on the version.

Method 2: Change configuration at the application level (available only for the .NET Framework version 4.6 and later versions)

Starting with the .NET Framework 4.6, you can change the configuration at an application level through code or application configuration or registry changes.In the .NET Framework 4.6, you can set the switch by using any of the following methods. These examples disable the security feature.

  • ProgrammaticallyThe first thing that the application should do is run the following code. This is because Service Point Manager will initialize only one time.

    private const string DisableCachingName = @"TestSwitch.LocalAppContext.DisableCaching"; private const string DontEnableSchSendAuxRecordName = @"Switch.System.Net.DontEnableSchSendAuxRecord"; AppContext.SetSwitch(DisableCachingName, true); AppContext.SetSwitch(DontEnableSchSendAuxRecordName , true);
  • Application configurationTo change the application configuration, add the following entry:

    <runtime><AppContextSwitchOverrides value="Switch.System.Net.DontEnableSchSendAuxRecord=true"/></runtime>
  • Registry key (computer global)

    Registry locations:HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\AppContextHKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\AppContextValue: Switch.System.Net.DontEnableSchSendAuxRecord Type: StringValue: TrueNote Switch.System.Net.DontEnableSchSendAuxRecord = False for all applications.

More Information

The following is a sample Client/Server communication pattern before and after this update is installed. This information is provided for illustration for identifying any application breakage because of the installation of this fix.

Without the mitigation

With the mitigation

[Server] waiting for connections (127.0.0.1:4431) [Client] Connecting to localhost:4431 [Server] Client connected. [Client] Connected. Authenticating... [Server] Client authenticated. [Client] Sending request (94 Bytes) [Client] Waiting for reply… [Server] Received 94 bytes: <<<GET / HTTP/1.0 Host: contoso.com User-Agent: Testing application >>> [Server] Replied with 476 bytes. [Client 1: 476 Bytes] Response: <<<<<HTTP/1.1 200 OK>>>>>

[Server] waiting for connections (127.0.0.1:4431) [Client] Connecting to localhost:4431 [Server] Client connected. [Client] Connected. Authenticating... [Server] Client authenticated. [Client] Sending request (94 Bytes) [Client] Waiting for reply... [Server] Received 1 bytes: <<<G>>> [Server] Received 93 bytes: <<<ET / HTTP/1.0 Host: contoso.com User-Agent: Testing application >>> [Server] Replied with 476 bytes. [Client 1: 1 Bytes] Response: <<<<<H>>>>> [Client 2: 475 Bytes] Response: <<<<<TTP/1.1 200 OK >>>>>

Need more help?

Want more options?

Explore subscription benefits, browse training courses, learn how to secure your device, and more.

Communities help you ask and answer questions, give feedback, and hear from experts with rich knowledge.