Skip to content
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

crypto/tls: disable client-side TLS 1.0 and TLS 1.1 #45428

Closed
FiloSottile opened this issue Apr 7, 2021 · 40 comments
Closed

crypto/tls: disable client-side TLS 1.0 and TLS 1.1 #45428

FiloSottile opened this issue Apr 7, 2021 · 40 comments
Labels
FrozenDueToAge Proposal Proposal-Accepted Proposal-Crypto Proposal related to crypto packages or other security issues release-blocker
Milestone

Comments

@FiloSottile
Copy link
Contributor

FiloSottile commented Apr 7, 2021

TLS 1.0 and TLS 1.1 are legacy versions of TLS with significant robustness and complexity issues. They use SHA-1 in the handshake and they don't support AEAD cipher suites, meaning they require Encrypt-then-MAC CBC cipher suites that are vulnerable to side channel attacks. TLS 1.0 requires clunky countermeasures for attacks against CBC cipher suites.

TLS 1.2 was standardized in 2008. RFC 8996 strongly deprecated TLS 1.0 and TLS 1.1. All modern browsers removed support for TLS 1.0 and TLS 1.1 in 2020. PCI compliance has required TLS 1.2 since 2018. NIST guidelines require TLS 1.1 since 2014 and TLS 1.2 since 2019.

In terms of how the real world looks like, SSL Pulse says that only 0.7% of surveyed sites only support TLS 1.0. No websites supports TLS 1.1 but not TLS 1.2. Note that this data is not weighted by popularity. Since browsers removed TLS 1.0 and TLS 1.1 support, there are no connections numbers, but it was significantly lower before turndown.

On the client side the landscape is not as bright. Can I use says only 98.16% of web clients support TLS 1.2. I remember server-side connection numbers to be a little better, but not as good as client-side numbers.

There is also generally a qualitative difference between TLS 1.0 clients and TLS 1.0 servers. The former imply an outdated device, which can be expensive to replace, but possibly still serviceable. The latter implies a catastrophically out of date server which is not safe to use and must be updated.

Based on this, I propose a multi-stage plan for turning off and eventually removing TLS 1.0 and TLS 1.1.

I am requesting approval for the first stage, and will go through the proposal process again for each successive stage.

Stage 1

When zero, Config.MinVersion is changed to default to VersionTLS12 on the client side.

This can be overridden by setting Config.MinVersion (or with a temporary GODEBUG value).

Pre-announce this in Go 1.17, implement it in Go 1.18, remove the GODEBUG switch in Go 1.19.

Stage 2

When zero, Config.MinVersion is changed to default to VersionTLS12 on the server side.

This can be overridden by setting Config.MinVersion (or with a temporary GODEBUG value).

Pre-announce this in TBD, implement it in TBD+1, remove the GODEBUG switch in TBD+2.

(Stage 2, whenever it comes, might also be a good time to disable by default TLS 1.0-correlated ciphersuites like 3DES.)

Stage 3

TLS 1.0 and TLS 1.1 are turned off.

This can be temporarily overridden by both setting Config.MinVersion and a GODEBUG value simultaneously.

Pre-announce this in TBD, implement it in TBD+1, remove the GODEBUG switch and all TLS 1.0 and TLS 1.1 code in TBD+2.

(Stage 3, whenever it comes, might also be a good time to remove other off-by-default things like RC4 and 3DES.)

@gopherbot gopherbot added this to the Proposal milestone Apr 7, 2021
@FiloSottile FiloSottile added the Proposal-Crypto Proposal related to crypto packages or other security issues label Apr 7, 2021
@tmthrgd
Copy link
Contributor

tmthrgd commented Apr 7, 2021

Stage 3 seems like a copy-paste typo. If the protocols have been removed (code yeeted), then I don’t see how they could possibly be re-enabled
at run-time.

@FiloSottile
Copy link
Contributor Author

Stage 3 seems like a copy-paste typo. If the protocols have been removed (code yeeted), then I don’t see how they could possibly be re-enabled at run-time.

The code will be yeeted at TBD+2, in TBD+1 it will behave as if it was removed unless GODEBUG is set. The difference is that Config.MinVersion will stop working.

@tmthrgd
Copy link
Contributor

tmthrgd commented Apr 7, 2021

Stage 3 seems like a copy-paste typo. If the protocols have been removed (code yeeted), then I don’t see how they could possibly be re-enabled at run-time.

The code will be yeeted at TBD+2, in TBD+1 it will behave as if it was removed unless GODEBUG is set. The difference is that Config.MinVersion will stop working.

Ah I see, I see. That makes sense. It might help to clarify that in “This can be temporarily overridden with both Config.MinVersion and a GODEBUG value.” because that seems to state they’d both keep working during the transition.

@rsc rsc changed the title proposal: crypto/tls: gradually turn off TLS 1.0 and TLS 1.1 proposal: crypto/tls: disable client-side TLS 1.0 and TLS 1.1 Apr 7, 2021
@rsc
Copy link
Contributor

rsc commented Apr 7, 2021

Retitled to be clear this proposal discussion and potential approval is only for "Stage 1".

@rsc
Copy link
Contributor

rsc commented Apr 7, 2021

This proposal has been added to the active column of the proposals project
and will now be reviewed at the weekly proposal review meetings.
— rsc for the proposal review group

@ucirello
Copy link
Contributor

ucirello commented Apr 7, 2021

I'd like to oppose this proposal - both its first stage and in its entirety. With the caveat that I would be OK to replace the code I use with an extended library version of the packages (golang.org/x).

The data you put forward assumes publicly visible servers. In private networking the mentality that says "if it is not broken, don't fix it" creates a dramatically different reality. The fact is that I still need to interface with a lot of software with broken crypto (SSLv3, TLS1.0 etc).

The introduction and adoption of this proposal would create me a very big problem - in order to keep interfacing with old software, I would have to keep my own go installation frozen in time, or bear the cost of keeping a fork.

Please, reconsider this proposal - either don't proceed with it, or offer an extended library that I could keep using.

Thanks @FiloSottile @rsc

@FiloSottile
Copy link
Contributor Author

The fact is that I still need to interface with a lot of software with broken crypto (SSLv3, TLS1.0 etc).

If you need SSLv3 I assume you are already using a fork?

Since this is a proposal for approval of Stage 1, are you saying you need to connect to servers which don't support TLS 1.2? That would imply no modern browsers can connect to them either, so could you share what kind of software that is? How does that software get security updates? What timeline would you estimate for that software to get TLS 1.2 support?

@ucirello
Copy link
Contributor

ucirello commented Apr 7, 2021

If you need SSLv3 I assume you are already using a fork?

Or in my case, I have at least some deployments running an old version of the code. So these customers are stuck with older versions.

Since this is a proposal for approval of Stage 1, are you saying you need to connect to servers which don't support TLS 1.2?

Correct

That would imply no modern browsers can connect to them either, so could you share what kind of software that is?

Database Protocols Software and ancient deployments of remote desktop sharing software.

How does that software get security updates? What timeline would you estimate for that software to get TLS 1.2 support?

I don't believe they do. And the timeline is none. Because, "if it is not broken, don't fix it". Sad, I know.

@FiloSottile
Copy link
Contributor Author

How does that software get security updates? What timeline would you estimate for that software to get TLS 1.2 support?

I don't believe they do. And the timeline is none. Because, "if it is not broken, don't fix it". Sad, I know.

I feel for who has to maintain those systems, but making modern well-run systems pay (because remember that complexity has a security cost, in more ways than one) for systems that decided to be permanently insecure is not an option, sorry.

Anyway, it sounds like you wouldn't be affected by this change until Stage 3. Do you have any objections to Stage 1? Why?

@mvdan
Copy link
Member

mvdan commented Apr 7, 2021

Presumably, systems insisting on sticking to deprecated versions of TLS could also just stay on an older version of Go? I get that upgrading Go has other benefits, but I'm fully with @FiloSottile that keeping that use case working for a long time seems like the wrong tradeoff.

@ucirello
Copy link
Contributor

ucirello commented Apr 7, 2021

Do you have any objections to Stage 1? Why?

It depends on how the Stage 1 shows ups. If it is a parameter (Config.MinVersion override), then it is fine. Adjusting the behavior through env vars (like GODEBUG) is a way harder sell - I'd have to either ask my customers to deploy a configuration change (tough sell - "it is working, why do you want me to change it?").

I feel for who has to maintain those systems, but making modern well-run systems pay (because remember that complexity has a security cost, in more ways than one) for systems that decided to be permanently insecure is not an option, sorry.

I agree with you, and that's why I suggested keeping the deprecated software under golang.org/x. But perhaps it doesn't make sense? I defer to you.

systems insisting on sticking to deprecated versions of TLS could also just stay on an older version of Go?

I tried it - it works well. As long as my dependencies decide their minimum go versions is as old or older than the old Go version I'd need to keep around, plus manually back-porting other Go changes (non-crypto changes) into the old Go version. If possible, I'd like to avoid this situation.

@FiloSottile
Copy link
Contributor Author

FiloSottile commented Apr 7, 2021

Do you have any objections to Stage 1? Why?

It depends on how the Stage 1 shows ups. If it is a parameter (Config.MinVersion override), then it is fine. Adjusting the behavior through env vars (like GODEBUG) is a way harder sell - I'd have to either ask my customers to deploy a configuration change (tough sell - "it is working, why do you want me to change it?").

Stage 1 and 2 just change the default MinVersion value. GODEBUG is never a long term setting, it's just a way to easily triage a failure by setting something in the environment without going around rebuilding everything involved.

Edit: clarified in the proposal that Stage 1 and 2 effectively change the default Config.MinVersion.

I feel for who has to maintain those systems, but making modern well-run systems pay (because remember that complexity has a security cost, in more ways than one) for systems that decided to be permanently insecure is not an option, sorry.

I agree with you, and that's why I suggested keeping the deprecated software under golang.org/x. But perhaps it doesn't make sense? I defer to you.

Unfortunately the TLS stack is not easy to swap in and out: #21753. It would be nice to make it easier and is something we keep in mind as we plan larger changes. In general, we also can't maintain forks for everyone's custom requirements, so it would have to be a community project.

@ucirello
Copy link
Contributor

ucirello commented Apr 7, 2021

Unfortunately the TLS stack is not easy to swap in and out: #21753. It would be nice to make it easier and is something we keep in mind as we plan larger changes. In general, we also can't maintain forks for everyone's custom requirements, so it would have to be a community project.

In any case, thanks for caring @FiloSottile

@antichris

This comment has been minimized.

@FiloSottile

This comment has been minimized.

@antichris

This comment has been minimized.

@liuxingbaoyu
Copy link

I know that many users are using 512m memory servers to run their software, XP win 2003, win7 systems, WINAPI does not support TLS1.2 (win7 can be supported by an update patch), so some server also needs to retain TLS1.2.
So I am not opposed to modifying Config.MinVersion, but I think the old version of TLS code should be retained and can be enabled, otherwise some service providers can only use the old version of golang on the server for customers, which will bring greater risks and a lot of inconvenience.

@ghost
Copy link

ghost commented Apr 8, 2021

I know that many users are using 512m memory servers to run their software, XP win 2003, win7 systems, WINAPI does not support TLS1.2 (win7 can be supported by an update patch), so some server also needs to retain TLS1.2.
So I am not opposed to modifying Config.MinVersion, but I think the old version of TLS code should be retained and can be enabled, otherwise some service providers can only use the old version of golang on the server for customers, which will bring greater risks and a lot of inconvenience.

Let's say a programmer who doesn't know about this flaw implements this into their code, and they work for a bank and makes it into production, than they are screwed, I say we remove it from the standard package and maybe add it to another package. (non-standard one) and if they really want to use it they still have the option to import it from another package.

@liuxingbaoyu
Copy link

I know that many users are using 512m memory servers to run their software, XP win 2003, win7 systems, WINAPI does not support TLS1.2 (win7 can be supported by an update patch), so some server also needs to retain TLS1.2.
So I am not opposed to modifying Config.MinVersion, but I think the old version of TLS code should be retained and can be enabled, otherwise some service providers can only use the old version of golang on the server for customers, which will bring greater risks and a lot of inconvenience.

Let's say a programmer who doesn't know about this flaw implements this into their code, and they work for a bank and makes it into production, than they are screwed, I say we remove it from the standard package and maybe add it to another package. (non-standard one) and if they really want to use it they still have the option to import it from another package.

Yeah, as long as there is an easy way to enable it. In fact, Config.MinVersion is a reminder, and we can even raise a warning when MinVersion<=TLS1.2.
Regarding moving out of the standard library, it seems difficult.

Unfortunately the TLS stack is not easy to swap in and out: #21753. It would be nice to make it easier and is something we keep in mind as we plan larger changes. In general, we also can't maintain forks for everyone's custom requirements, so it would have to be a community project.

#45428 (comment)

@rsc
Copy link
Contributor

rsc commented Apr 14, 2021

Again, this issue is about disabling support for connecting to ancient servers.
Serving (talking to) an ancient client is not affected by this issue.

It sounds like a few people are concerned about disabling by default but are OK with setting Config.MinVersion to opt out.
They would be less happy with GODEBUG, but it's fine to have as well for debugging purposes.

Do I have that right?

@ucirello
Copy link
Contributor

It sounds like a few people are concerned about disabling by default but are OK with setting Config.MinVersion to opt out.
They would be less happy with GODEBUG, but it's fine to have as well for debugging purposes.

Do I have that right?

Yes. I can live with Config.MinVersion changes. GODEBUG would create actual problems that are way harder to solve (and probably involves func init() + os.Setenv() hacks to inject changes to GODEBUG).

@pedroalbanese

This comment has been minimized.

@seankhliao

This comment has been minimized.

@pedroalbanese

This comment has been minimized.

@ianlancetaylor
Copy link
Member

@FiloSottile @golang/security This is in the 1.18 milestone. Is there something that is supposed to happen here for 1.18?

I see that in the 1.17 release notes we said "Beginning in the next release, Go 1.18, the Config.MinVersion for crypto/tls clients will default to TLS 1.2, disabling TLS 1.0 and TLS 1.1 by default. Applications will be able to override the change by explicitly setting Config.MinVersion. This will not affect crypto/tls servers."

Did that happen?

Thanks.

@gopherbot
Copy link
Contributor

Change https://golang.org/cl/382454 mentions this issue: doc/go1.18: add crypto/tls, crypto/x509, and crypto/elliptic release notes

@FiloSottile
Copy link
Contributor Author

All the work is done, I just mailed the release note, bumping to Go 1.19 to remove the GODEBUG flag.

@FiloSottile FiloSottile modified the milestones: Go1.18, Go1.19 Feb 2, 2022
gopherbot pushed a commit that referenced this issue Feb 2, 2022
…notes

Updates #45428
Updates #41682

Change-Id: I811bc4f8ec8de6b6db6a2917e265a72134a05e78
Reviewed-on: https://go-review.googlesource.com/c/go/+/382454
Trust: Filippo Valsorda <filippo@golang.org>
Trust: Katie Hockman <katie@golang.org>
Reviewed-by: Katie Hockman <katie@golang.org>
@cherrymui
Copy link
Member

@FiloSottile is there anything to be done for Go 1.19? Checking in as this is a release blocker. Thanks.

@FiloSottile
Copy link
Contributor Author

Yeah, we just need to remove the GODEBUG flag. I'll send a CL in the next week.

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/400974 mentions this issue: crypto/tls: remove tls10default GODEBUG flag

gopherbot pushed a commit that referenced this issue Apr 27, 2022
Updates #45428

Change-Id: Ic2ff459e6a3f1e8ded2a770c11d34067c0b39a8a
Reviewed-on: https://go-review.googlesource.com/c/go/+/400974
Reviewed-by: Filippo Valsorda <valsorda@google.com>
Auto-Submit: Filippo Valsorda <valsorda@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Filippo Valsorda <valsorda@google.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
@mknyszek
Copy link
Contributor

Should this issue be closed? Is there anything else to do here for Go 1.19?

@lpar
Copy link

lpar commented Sep 30, 2022

So just for clarity, the plan to remove "all TLS 1.0 and TLS 1.1 code" in stage 3 was abandoned?

@FiloSottile
Copy link
Contributor Author

No, but its time has definitely not come yet. Stage 2 has not happened yet, either. When it makes sense for them to happen there will be a new proposal.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge Proposal Proposal-Accepted Proposal-Crypto Proposal related to crypto packages or other security issues release-blocker
Projects
None yet
Development

No branches or pull requests