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

Open
FiloSottile opened this issue Apr 7, 2021 · 27 comments
Open

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

FiloSottile opened this issue Apr 7, 2021 · 27 comments

Comments

@FiloSottile
Copy link
Contributor

@FiloSottile 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
@tmthrgd
Copy link
Contributor

@tmthrgd 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

@FiloSottile FiloSottile 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.

@tmthrgd
Copy link
Contributor

@tmthrgd 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.

@ianlancetaylor ianlancetaylor added this to Incoming in Proposals Apr 7, 2021
@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 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 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

@rsc rsc moved this from Incoming to Active in Proposals Apr 7, 2021
@ucirello
Copy link
Contributor

@ucirello 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

@FiloSottile FiloSottile commented Apr 7, 2021

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 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

@FiloSottile FiloSottile commented Apr 7, 2021

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 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 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 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 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 was marked as off-topic.

@FiloSottile

This comment has been hidden.

@antichris

This comment was marked as off-topic.

@liuxingbaoyu
Copy link

@liuxingbaoyu liuxingbaoyu 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.

@Prajwal-Koirala
Copy link
Contributor

@Prajwal-Koirala Prajwal-Koirala 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

@liuxingbaoyu liuxingbaoyu 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.

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 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

@ucirello ucirello commented Apr 14, 2021

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).

@rsc rsc moved this from Active to Likely Accept in Proposals Apr 21, 2021
@rsc
Copy link
Contributor

@rsc rsc commented Apr 21, 2021

Based on the discussion above, this proposal seems like a likely accept.
— rsc for the proposal review group

@rsc rsc moved this from Likely Accept to Accepted in Proposals Apr 28, 2021
@rsc
Copy link
Contributor

@rsc rsc commented Apr 28, 2021

No change in consensus, so accepted. 🎉
This issue now tracks the work of implementing the proposal.
— rsc for the proposal review group

@rsc rsc changed the title proposal: crypto/tls: disable client-side TLS 1.0 and TLS 1.1 crypto/tls: disable client-side TLS 1.0 and TLS 1.1 Apr 28, 2021
@rsc rsc removed this from the Proposal milestone Apr 28, 2021
@rsc rsc added this to the Backlog milestone Apr 28, 2021
@ucirello
Copy link
Contributor

@ucirello ucirello commented Apr 29, 2021

@rsc could you please provide a clarification on what is made here? config.MinVersion or GODEBUG env var?

@FiloSottile
Copy link
Contributor Author

@FiloSottile FiloSottile commented Apr 29, 2021

@ucirello this is the final text of the proposal as accepted, above.

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.

@ucirello
Copy link
Contributor

@ucirello ucirello commented Apr 29, 2021

I apologize - I missed.

Thanks for pointing it out @FiloSottile

@gopherbot
Copy link

@gopherbot gopherbot commented Jun 15, 2021

Change https://golang.org/cl/327811 mentions this issue: doc/go1.17: add Go 1.18 pre-announcements

gopherbot pushed a commit that referenced this issue Jun 21, 2021
Updates #41682
Updates #45428

Change-Id: Ia31d454284f0e114bd29ba398a2858fc90454032
Reviewed-on: https://go-review.googlesource.com/c/go/+/327811
Trust: Filippo Valsorda <filippo@golang.org>
Trust: Katie Hockman <katie@golang.org>
Reviewed-by: Katie Hockman <katie@golang.org>
@FiloSottile FiloSottile removed this from the Backlog milestone Aug 31, 2021
@FiloSottile FiloSottile added this to the Go1.18 milestone Aug 31, 2021
@FiloSottile FiloSottile self-assigned this Aug 31, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Proposals
Accepted
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
9 participants