-
Notifications
You must be signed in to change notification settings - Fork 6.1k
Update security docs to address outdated cryptographic defaults, broken samples, and weak recommendations #53164
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 20 commits
f4d3143
3e12992
457c5df
b70d56b
62c2f8e
acfaaeb
0fbb4be
e440169
b5e2bbd
a356a6b
a512d7a
59997bc
a85b170
2309655
cc3f5e8
1e65834
ea76609
a812155
2840c50
20355a3
cb76bf4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,19 +9,22 @@ ms.assetid: 33f97d13-3022-43da-8b18-cdb5c88df9c2 | |
| --- | ||
| # Mitigation: TLS Protocols | ||
|
|
||
| Starting with .NET Framework 4.6, the <xref:System.Net.ServicePointManager?displayProperty=nameWithType> and <xref:System.Net.Security.SslStream?displayProperty=nameWithType> classes are allowed to use one of the following three protocols: Tls1.0, Tls1.1, or Tls 1.2. The SSL3.0 protocol and RC4 cipher are not supported. | ||
| Starting with .NET Framework 4.6, the <xref:System.Net.ServicePointManager?displayProperty=nameWithType> and <xref:System.Net.Security.SslStream?displayProperty=nameWithType> classes negotiate TLS 1.0, TLS 1.1, or TLS 1.2 based on OS support. The SSL 3.0 protocol and RC4 cipher are not supported. | ||
|
|
||
| > [!WARNING] | ||
| > This article documents a legacy compatibility change in .NET Framework 4.6. For current deployments, use operating system defaults and allow only TLS 1.2 or TLS 1.3 when available. For more information, see [Transport Layer Security (TLS) best practices with the .NET Framework](../network-programming/tls.md). | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think mentioning specific TLS version is not future proof unless we mention "as of 2026" somewhere but that doesn't sound very good
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The metadata says this is "Learn about the impact and mitigation for the TLS Protocol changes beginning with .NET Framework 4.6.". I don't understand why we'd include "Warning: Knives are sharp." in such a document. |
||
|
|
||
| ## Impact | ||
|
|
||
| This change affects: | ||
|
|
||
| - Any app that uses SSL to talk to an HTTPS server or a socket server using any of the following types: <xref:System.Net.Http.HttpClient>, <xref:System.Net.HttpWebRequest>, <xref:System.Net.FtpWebRequest>, <xref:System.Net.Mail.SmtpClient>, and <xref:System.Net.Security.SslStream>. | ||
|
|
||
| - Any server-side app that cannot be upgraded to support Tls1.0, Tls1.1, or Tls 1.2.. | ||
| - Any server-side app that cannot be upgraded to support modern TLS configurations, ideally TLS 1.2 or later. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd just drop the last part |
||
|
|
||
| ## Mitigation | ||
|
|
||
| The recommended mitigation is to upgrade the sever-side app to Tls1.0, Tls1.1, or Tls 1.2. If this is not feasible, or if client apps are broken, the <xref:System.AppContext> class can be used to opt out of this feature in either of two ways: | ||
| The recommended mitigation is to upgrade the server-side app to support modern TLS configurations. If that isn't feasible, or if client apps are broken, the <xref:System.AppContext> class can be used to opt out of this feature in either of two ways as a temporary compatibility workaround: | ||
|
|
||
| - Programmatically, by using a code snippet like the following: | ||
|
|
||
|
|
@@ -36,7 +39,7 @@ Starting with .NET Framework 4.6, the <xref:System.Net.ServicePointManager?displ | |
| <AppContextSwitchOverrides value="Switch.System.Net.DontEnableSchUseStrongCrypto=true"/> | ||
| ``` | ||
|
|
||
| Note, however, that opting out of the default behavior is not recommended, since it makes the application less secure. | ||
| Note, however, that opting out of the default behavior is not recommended, since it makes the application less secure. | ||
|
|
||
| ## See also | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -24,7 +24,7 @@ helpviewer_keywords: | |||||
| ## What is Transport Layer Security (TLS)? | ||||||
|
|
||||||
| > [!WARNING] | ||||||
| > TLS 1.0 and 1.1 has been deprecated by [RFC8996](https://datatracker.ietf.org/doc/rfc8996/). This document covers TLS 1.2 and TLS 1.3 only. | ||||||
| > TLS 1.0 and TLS 1.1 have been deprecated by [RFC 8996](https://datatracker.ietf.org/doc/rfc8996/). Current [NIST SP 800-52 Rev. 2](https://csrc.nist.gov/pubs/sp/800/52/r2/final) guidance requires TLS 1.2 and recommends TLS 1.3 when available. This document covers TLS 1.2 and TLS 1.3 only. | ||||||
|
|
||||||
| The Transport Layer Security (TLS) protocol is an industry latest version of the standard designed to help protect the privacy of information communicated over the Internet. [TLS 1.3](https://tools.ietf.org/html/rfc8446) is a standard that provides security improvements over previous versions. This article presents recommendations to secure .NET Framework applications that use the TLS protocol. | ||||||
|
|
||||||
|
|
@@ -70,7 +70,7 @@ When your app lets the OS choose the TLS version: | |||||
|
|
||||||
| This article explains how to enable the strongest security available for the version of .NET Framework that your app targets and runs on. When an app explicitly sets a security protocol and version, it opts out of any other alternative, and opts out of .NET Framework and OS default behavior. If you want your app to be able to negotiate a TLS 1.3 connection, explicitly setting to a lower TLS version prevents a TLS 1.3 connection. | ||||||
|
|
||||||
| If you can't avoid specifying a protocol version explicitly, we strongly recommend that you specify TLS 1.2 or TLS 1.3 (which is `currently considered secure`). For guidance on identifying and removing TLS 1.0 dependencies, download the [Solving the TLS 1.0 Problem](https://www.microsoft.com/download/details.aspx?id=55266) white paper. | ||||||
| If you can't avoid specifying a protocol version explicitly, allow only TLS 1.2 or TLS 1.3. Prefer TLS 1.3 when the operating system and peer support it. For guidance on identifying and removing TLS 1.0 dependencies, download the [Solving the TLS 1.0 Problem](https://www.microsoft.com/download/details.aspx?id=55266) white paper. | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. perhaps something along the lines of "allow only NIST approved TLS versions which at time of writing this document are TLS 1.2 and TLS 1.3" |
||||||
|
|
||||||
| WCF supports TLS 1.2 as the default in .NET Framework 4.7. Starting with .NET Framework 4.7.1, WCF defaults to the operating system configured version. If an application is explicitly configured with `SslProtocols.None`, WCF uses the operating system default setting when using the NetTcp transport. | ||||||
|
|
||||||
|
|
@@ -139,7 +139,7 @@ Because the <xref:System.Net.SecurityProtocolType.SystemDefault?displayProperty= | |||||
|
|
||||||
| #### For SslStream | ||||||
|
|
||||||
| <xref:System.Net.Security.SslStream> defaults to the security protocol and version chosen by the OS. To get the default OS best choice, if possible, don't use the method overloads of <xref:System.Net.Security.SslStream> that take an explicit <xref:System.Security.Authentication.SslProtocols> parameter. Otherwise, pass <xref:System.Security.Authentication.SslProtocols.None?displayProperty=nameWithType>. We recommend that you don't use <xref:System.Security.Authentication.SslProtocols.Default>; setting `SslProtocols.Default` forces the use of SSL 3.0 /TLS 1.0 and prevents TLS 1.2. | ||||||
| <xref:System.Net.Security.SslStream> defaults to the security protocol and version chosen by the OS. To get the default OS best choice, if possible, don't use the method overloads of <xref:System.Net.Security.SslStream> that take an explicit <xref:System.Security.Authentication.SslProtocols> parameter. Otherwise, pass <xref:System.Security.Authentication.SslProtocols.None?displayProperty=nameWithType>. We recommend that you don't use <xref:System.Security.Authentication.SslProtocols.Default>; setting `SslProtocols.Default` forces the use of SSL 3.0 /TLS 1.0 and prevents negotiation of newer versions. | ||||||
|
|
||||||
| Don't set a value for the <xref:System.Net.ServicePointManager.SecurityProtocol> property (for HTTP networking). | ||||||
|
|
||||||
|
|
@@ -160,7 +160,7 @@ If you're targeting 4.7.1, WCF is configured to allow the OS to choose the best | |||||
| - In your application configuration file. | ||||||
| - **Or**, in your application in the source code. | ||||||
|
|
||||||
| By default, .NET Framework 4.7 and later versions are configured to use TLS 1.2 and allow connections using TLS 1.1 or TLS 1.0. Configure WCF to allow the OS to choose the best security protocol by configuring your binding to use <xref:System.Security.Authentication.SslProtocols.None?displayProperty=nameWithType>. You can set this on <xref:System.ServiceModel.TcpTransportSecurity.SslProtocols>. `SslProtocols.None` can be accessed from <xref:System.ServiceModel.NetTcpSecurity.Transport>. `NetTcpSecurity.Transport` can be accessed from <xref:System.ServiceModel.NetTcpBinding.Security>. | ||||||
| By default, .NET Framework 4.7 and later versions are configured to use TLS 1.2 and allow connections using TLS 1.1 or TLS 1.0. Don't rely on those older protocols. Configure WCF to allow the OS to choose the best security protocol by configuring your binding to use <xref:System.Security.Authentication.SslProtocols.None?displayProperty=nameWithType>. You can set this on <xref:System.ServiceModel.TcpTransportSecurity.SslProtocols>. `SslProtocols.None` can be accessed from <xref:System.ServiceModel.NetTcpSecurity.Transport>. `NetTcpSecurity.Transport` can be accessed from <xref:System.ServiceModel.NetTcpBinding.Security>. | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not certain this is true because IIRC TLS 1.3 says that if both side can talk TLS 1.3 they MUST talk TLS 1.3 and IIRC we did add support for TLS 1.3. Possibly more generic statement will be better here. @bartonjs ideas?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The recommendation is correct: Set your protocols to None, which SslStream interprets as "no preference, do whatever the OS says". And that's as far of an opinion as this document should have.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes about recommendation, comment was about |
||||||
|
|
||||||
| If you're using a custom binding: | ||||||
|
|
||||||
|
|
@@ -171,7 +171,7 @@ If you're **not** using a custom binding **and** you're setting your WCF binding | |||||
|
|
||||||
| #### Using Message Security with certificate credentials | ||||||
|
|
||||||
| .NET Framework 4.7 and later versions by default use the protocol specified in the <xref:System.Net.ServicePointManager.SecurityProtocol> property. When the [AppContextSwitch](../configure-apps/file-schema/runtime/appcontextswitchoverrides-element.md) `Switch.System.ServiceModel.DisableUsingServicePointManagerSecurityProtocols` is set to `true`, WCF chooses the best protocol, up to TLS 1.0. | ||||||
| .NET Framework 4.7 and later versions by default use the protocol specified in the <xref:System.Net.ServicePointManager.SecurityProtocol> property. When the [AppContextSwitch](../configure-apps/file-schema/runtime/appcontextswitchoverrides-element.md) `Switch.System.ServiceModel.DisableUsingServicePointManagerSecurityProtocols` is set to `true`, WCF chooses the best protocol, up to TLS 1.0. That compatibility path is for legacy scenarios and doesn't satisfy current security guidance. | ||||||
|
|
||||||
| #### [.NET Framework 4.6.2 and earlier](#tab/462-minus) | ||||||
|
|
||||||
|
|
@@ -191,7 +191,7 @@ The switches have the same effect whether you're doing HTTP networking (<xref:Sy | |||||
|
|
||||||
| #### Switch.System.Net.DontEnableSchUseStrongCrypto | ||||||
|
|
||||||
| A value of `false` for `Switch.System.Net.DontEnableSchUseStrongCrypto` causes your app to use strong cryptography. A value of `false` for `DontEnableSchUseStrongCrypto` uses more secure network protocols (TLS 1.2 and TLS 1.1) and blocks protocols that are not secure. For more info, see [The SCH_USE_STRONG_CRYPTO flag](#the-sch_use_strong_crypto-flag). A value of `true` disables strong cryptography for your app. This switch affects only client (outgoing) connections in your application. | ||||||
| A value of `false` for `Switch.System.Net.DontEnableSchUseStrongCrypto` causes your app to use strong cryptography. A value of `false` for `DontEnableSchUseStrongCrypto` uses modern network protocols, such as TLS 1.2 and TLS 1.3 when available, and blocks protocols that are not secure. For more info, see [The SCH_USE_STRONG_CRYPTO flag](#the-sch_use_strong_crypto-flag). A value of `true` disables strong cryptography for your app. This switch affects only client (outgoing) connections in your application. | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Don't mention versions if you can help it, that way we don't have to come back in a few years and debate "should this 'and 1.3' also include 1.4 now?, or was it point-in-time?" |
||||||
|
|
||||||
| If your app targets .NET Framework 4.6.2 or later versions, this switch defaults to `false`. That's a secure default, which we recommend. If your app runs on .NET Framework 4.6.2, but targets an earlier version, the switch defaults to `true`. In that case, you should explicitly set it to `false`. | ||||||
|
|
||||||
|
|
@@ -207,7 +207,7 @@ If your app targets .NET Framework 4.7 or later versions, this switch defaults t | |||||
|
|
||||||
| #### Switch.System.ServiceModel.DisableUsingServicePointManagerSecurityProtocols | ||||||
|
|
||||||
| A value of `false` for `Switch.System.ServiceModel.DisableUsingServicePointManagerSecurityProtocols` causes your application to use the value defined in `ServicePointManager.SecurityProtocols` for message security using certificate credentials. A value of `true` uses the highest protocol available, up to TLS1.0 | ||||||
| A value of `false` for `Switch.System.ServiceModel.DisableUsingServicePointManagerSecurityProtocols` causes your application to use the value defined in `ServicePointManager.SecurityProtocols` for message security using certificate credentials. A value of `true` uses the highest protocol available through that legacy compatibility path, which on older systems can still mean TLS 1.0. | ||||||
|
|
||||||
| For applications targeting .NET Framework 4.7 and later versions, this value defaults to `false`. For applications targeting .NET Framework 4.6.2 and earlier, this value defaults to `true`. | ||||||
|
|
||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,7 +19,10 @@ ms.assetid: 6e4289e6-d1b7-4e82-ab0d-e83e3b6063ed | |
| --- | ||
| # Using Secure Sockets Layer | ||
|
|
||
| The <xref:System.Net> classes use the Secure Sockets Layer (SSL) to encrypt the connection for several network protocols. | ||
| > [!WARNING] | ||
| > This article uses the historical "SSL" terminology from older .NET Framework APIs. For current guidance, use TLS rather than older SSL protocols, and prefer OS defaults. For more information, see [Transport Layer Security (TLS) best practices with the .NET Framework](tls.md). | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Might be worth to just updade this doc to use new terminology since we have tools for that but perhaps separate PR might be better idea
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The rewritten sentence (currently line 25) is good. The warning feels superfluous. [I advise that we should just] delete it. |
||
|
|
||
| The <xref:System.Net> classes use Transport Layer Security (TLS), historically referred to as Secure Sockets Layer (SSL), to encrypt the connection for several network protocols. | ||
|
|
||
| For http connections, the <xref:System.Net.WebRequest> and <xref:System.Net.WebResponse> classes use SSL to communicate with web hosts that support SSL. The decision to use SSL is made by the <xref:System.Net.WebRequest> class, based on the URI it is given. If the URI begins with "https:", SSL is used; if the URI begins with "http:", an unencrypted connection is used. | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is missing TLS 1.3 but probably better to make it more generic and future proof
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this is about a change made between 4.5.2 and 4.6, it's probably accurate as-is.
But, also, since it's about a change made between 4.5.2 and 4.6, I don't know why we're editing it.