[HN Gopher] Automatic cipher suite ordering in Go's crypto/tls
___________________________________________________________________
Automatic cipher suite ordering in Go's crypto/tls
Author : FiloSottile
Score : 86 points
Date : 2021-09-15 16:12 UTC (6 hours ago)
(HTM) web link (go.dev)
(TXT) w3m dump (go.dev)
| verdverm wrote:
| Note, that this is for TLS 1.0-2 and TLS 1.3 only has two options
| since it was implemented. For TLS 1.3...
|
| > In Go 1.16, we started actively preferring ChaCha20Poly1305
| cipher suites over AES-GCM on the server when we detect that
| either the client or the server lacks hardware support for AES-
| GCM. This is because AES-GCM is hard to implement efficiently and
| securely without dedicated hardware support (such as the AES-NI
| and CLMUL instruction sets).
| TheDong wrote:
| This seems at odds with the Go 1 compatibility promise. It's
| trivial to see that the go1.17 upgrade will break any program
| that relied on 'PreferServerCipherSuites' to run correctly.
|
| The Go 1 compatibility promise (https://golang.org/doc/go1compat)
| does have an exception for "new security issues that come to
| light", but this really doesn't seem like it's a new security
| issue, but rather closer to a defense in depth measure.
|
| I think the correct Go-like way to handle this is to deprecate
| the entire 'crypto/tls' package and tell users to use the
| 'v2/crypto/tls' package, akin to how go modules work.
|
| That new package could then not have the
| 'PreferServerCipherSuites' option at all, which would make it
| very clear when a user migrates that this change is occurring,
| and if they relied on it they must make an appropriate change to
| their code too.
|
| Obviously, the entire world would have to shift over (since a
| 'v2/crypto/tls.Conn' would not be compatible with a
| 'crypto/tls.Conn', it's a struct not an interface), but that also
| seems fair. It's what the go team tells users to do in the case
| of module versioning, so it seems quite consistent.
|
| I find it surprising there's no mention of backwards
| compatibility or the go1compat page in the CL or linked issues.
| Thaxll wrote:
| Go 1 compatibility promise is not about std lib API at large: a
| set of core APIs, the "standard packages" of the Go library.
|
| Also none of the std libs are versioned, and I don't see any
| time soon a v2 for it.
| TheDong wrote:
| > none of the std libs are versioned, and I don't see any
| time soon a v2 for it.
|
| There is one precedent: the syscall package
| (https://golang.org/s/go1.4-syscall)
|
| It was deprecated and replaced with the versioned
| 'golang.org/x/sys/unix' package instead.
|
| The reason the syscall package was changed to an x package
| was because the x package could be versioned better, and
| because the stdlib package had to make breaking changes.
|
| I'm more or less just asking why we don't do the same thing
| for tls, http, and any other packages that, like syscall,
| have issues that cannot be fixed in a backwards compatible
| way.
|
| It seems like we've ended up making inconsistent decisions
| here, which ultimately lead to go programs breaking during go
| compiler upgrades... which is a thing that isn't supposed to
| happen.
| ollien wrote:
| From that page:
|
| > Go 1 defines two things: first, the specification of the
| language; and second, the specification of a set of core
| APIs, the "standard packages" of the Go library.
|
| ...
|
| > The APIs may grow, acquiring new packages and features, but
| not in a way that breaks existing Go 1 code.
|
| So yes, it does apply to the standard library, AFAICT
| Thaxll wrote:
| I don't undertsand it that way, it's not all the std APIs,
| just some of them ( the core ones ).
| FiloSottile wrote:
| If you encounter such a program that requires
| PreferServerCipherSuites to run correctly, please open an issue
| and we'll look into it as a potential regression.
|
| More in general, it's unavoidable for packages that implement
| living protocols like TLS and HTTP to have a higher level
| concept of backwards compatibility: if the wire behavior of the
| package were to never change, Go would soon stop working with
| most of the ecosystem, and wouldn't implement the likes of
| HTTP/2 and TLS 1.3. Many standard libraries went that way, and
| ended up less useful and safe.
| mike_d wrote:
| This change will break my (and others) scanning the internet
| and enumerating supported cipher suites and server behavior.
|
| At least other footguns in Go are stuck into unsafe or
| something similar. Completely removing it will just force
| people to maintain local forks.
| tptacek wrote:
| It's already pretty common for people using Go's
| (excellent) TLS library for scanners to fork it; it's
| probably what you _should_ do, because there 's lots of
| opportunity for instrumentation that the library easily
| hosts but doesn't provide out of the box.
| FiloSottile wrote:
| My first intuition for how to do that would be to only
| enable one cipher suite at a time, which still works with
| this change. Still, do feel welcome to open an issue, I
| can't promise any specific outcome but we'll look at it.
|
| I'll mention that we had to ignore the requirements of
| diagnostic and scanning tools in the past, and you might be
| better served by a fork like BoGo from the BoringSSL test
| suite. Fundamentally, what an application wants ("make a
| secure connection") is at odds with what a test tool wants
| ("make a connection potentially broken in one of a thousand
| different ways, and tell me how it went").
| TheDong wrote:
| I don't know of any programs that will break from this
| specific change, though I will be unsurprising if some exist.
|
| I agree that the http and tls packages have made frequent
| changes that are technically exceptions to the go1compat
| promises, where there are changes that are technically
| breaking, but are "in spirit" with the intent of the package.
| I agree that it's unavoidable to change them over time in
| this way.
|
| The reality of this has been that http-related changes semi-
| frequently break my programs when I update go versions.
|
| To me, the fact that http and tls are living protocols is an
| argument for them being separate versioned modules (i.e.
| golang.orx/x/net/http), not that we should be causing
| breaking changes and hand-waving it as being an improvement.
|
| Other packages, like os, sync, etc, have remained stable, and
| I have no issue with those being versioned alongside the go
| distribution.
|
| For packages like http and tls, that have made frequent
| breaking changes, it does seem like they should have been
| deprecated and replaced with either golang.org/x/vX/net/http,
| or some in-stdlib-versioned-thing.
|
| Why not deprecate crypto/tls and move it out of the stdlib
| such that users can get benefits of updating the compiler
| without the risk of code breakage? It also seems like a
| benefit that users could then consume crypto/tls updates on a
| faster cadence without needing go point releases.
| FiloSottile wrote:
| That's generally something that might be desirable for a
| number of reasons but it's an extremely delicate change
| because of how stdlib packages import each other, and how
| types from x/ repos vendored back into the stdlib are not
| compatible with the original ones. You quickly have to ask
| questions like "do we let the main module upgrade the
| version of x/ repos used by the stdlib?" Maybe eventually
| we'll find a way to do this cleanly and decide to do it,
| but large changes like this take time.
| [deleted]
| er4hn wrote:
| Summary: The Golang team is deciding what ranked order TLS cipher
| suites should be used in. You are not able to decide what cipher
| suites to use, the Golang team sets that in the code and will
| update it as they see fit.
|
| My take on this is that Filippo is taking a heavy handed approach
| here. This works for the majority of "dev write code fast ship it
| over the wall" scenarios. But it also falls apart in a couple
| scenarios:
|
| * Companies/govt agencies which mandate the use of certain
| algorithms, such as RSA, and both sides of the connection are
| running Golang code. Now you need to vendor the TLS library to
| allow for what the company wants.
|
| * If an issue is discovered with an algorithm it would be really
| nice to be able to turn off the algorithm in production until the
| issue can be patched. I'm not sure if this is possible with the
| current set of changes.
| FiloSottile wrote:
| _o/ the summary is close, but there's a key detail that might
| have not come across: you can still enable and disable TLS
| 1.0-1.2 cipher suites. What we take care of is the preference
| order in which they are picked.
|
| The two scenarios you present aren't really affected by this
| change. However, I want to address the latter: if we fail to
| make it possible for Go applications to promptly roll out
| software security fixes, being able to change TLS configuration
| will be barely a band-aid. I actually can't remember the last
| time that would have helped secure a Go application faster.
| er4hn wrote:
| Thanks for the clarification. Being able to disable cipher
| suites in TLS <= 1.2 takes care of a lot of my concerns. It
| does still remain a concern for 1.3.
|
| I still do worry about the lack of ability to disable cipher
| suites. Does that extend to not being able to say "I will
| only accept certificates signed with RSA?" Because if you are
| forced to allow EC certificates then there are a couple
| points in the past where this could have been an issue (
| https://www.cvedetails.com/cve/CVE-2019-6486/ and
| https://www.cvedetails.com/cve/CVE-2021-3114/ ). Furthermore
| if we imagine a future where an issue is found with how one
| of the ciphersuites is implemented (say ChaCha20 is done
| incorrectly and we only want to allow AES-GCM) then being
| able to disable the known bad ciphersuite is a great band-
| aid.
|
| Let's say that you are providing a Go application to a
| customer. The customer can configure the application with a
| config file that controls TLS params. If you can configure
| the TLS ciphersuites and an issue is found the customer turns
| off the ciphersuite until they can upgrade. The alternative
| is that you go through a chain of: vendor gets new Golang ->
| rebuilds application -> does in-house testing to make sure
| nothing else came in the new Golang that broke stuff ->
| customer gets new application -> customer does their own in-
| house testing -> finally it gets deployed. It's a way longer
| cycle if you rely on upstream to push changes in code.
| FiloSottile wrote:
| Why do TLS issues need to get patched faster than any other
| security vulnerability? Or said another way, why is a slow
| deploy cycle ok for non-TLS vulnerabilities?
|
| So far I haven't heard any good reason. TLS issues are not
| more common than other components, at least in Go. Maybe
| people are just a little traumatized by how often other TLS
| stacks broke in the past?
|
| We maintain two Go versions with very conservative patch
| releases specifically to allow quick deployment of critical
| and security fixes. If that still doesn't allow for quick
| patching of security vulnerabilities, it sounds like a
| process issue (on our side or on the application side), not
| a reason to make TLS special.
| er4hn wrote:
| > why is a slow deploy cycle ok for non-TLS
| vulnerabilities?
|
| Okay, this is a fair point. I'd say that TLS is something
| where fixing it faster than the baseline is possible, if
| it had configurable knobs. In general we should of course
| strive to have fast deploy cycles for security
| vulnerabilities of all kinds.
| rootusrootus wrote:
| It would break in my use case, for sure. We routinely initiate
| TLS connections to crappy devices which have TLS
| implementations broken in ways that cause them to fail if you
| select the wrong cipher suite, even when the server otherwise
| claims to support it. Our ability to force this on a per-
| service basis is crucial to our success. We do not have the
| ability to fix the broken devices nor the luxury of not
| connecting to them.
| FiloSottile wrote:
| Can you open an issue elaborating on this? I'd expect the
| ability to disable broken cipher suites to be enough to work
| around this, and that is not changing. (What's going away is
| controlling the order in which enabled cipher suites are
| picked.)
| barsonme wrote:
| Any government agency that mandates use of specific TLS
| algorithms (like whitelist) almost certainly requires FIPS
| cryptography (or classified cryptography), so you won't be
| using crypto/TLS anyway.
|
| As a security/cryptography engineer, I love this change: for
| cryptography, it's clear that more knobs == more problems.
|
| As a developer, however, I dislike it: more knobs it's easier
| to get the code to do what I need it to do.
|
| Personally, I think it's a good choice by Filippo.
| wahern wrote:
| Isn't it mostly banks that want RSA key exchange, so their
| exfiltration detectors can sniff TLS streams?
|
| Shouldn't matter in this case, anyhow, as they would be
| disabling ephemeral KEX suites entirely.
| [deleted]
| er4hn wrote:
| I'll note that this follows the general trend of the Golang
| Security team trying to remove all the sharp edges on security
| code so that people don't cut themselves. I won't say that this
| is a uniformly bad thing, but it does make things harder.
|
| Another change in the same vein was removing official support
| for x/crypto/openpgp. There were no maintainers, it required
| too much effort, and pgp is in general a PITA to use. Totally
| understand. However this means that anyone working with signed
| git commits or signed rpm/deb packages is now using a forked
| library due to upstream dropping support.
| gunapologist99 wrote:
| I am always against taking choice away from developers. The
| setting of sane, up-to-the-minute defaults, which are always
| helpful, is not _at all_ what happened here.
|
| And, banal recommendations such as "just fork it then" are either
| not really serious or not in good faith. Should third-party
| developers really be encouraged to fork a key security component
| of the _standard library_ , just because it _no longer_ operates
| the way it used to?
|
| Personally, I welcome choosing better suites for me, but only as
| a default, and silently _overriding_ my carefully chosen settings
| will never be ok.
| jchw wrote:
| They _did_ remove the ability to control ordering for TLS 1.2
| cipher suites, but that's only because there's no logical
| reason anyone should change it. TLS 1.3 never allowed
| controlling this because it is unnecessary.
|
| When it comes to a crypto library, you really, really do not
| want configuration options beyond what is necessary. More
| configuration options is more opportunities for
| misconfigurations, and given the knowledge and skills required
| to fully understand the implications of these decisions as well
| as the consequences for doing it wrong, it is better to go
| without.
|
| These are lessons learned from the bad old days of crypto
| libraries. If the cipher ordering needs to be (objectively)
| suboptimal in your use case, it sounds like something is broken
| and you should actually expect to need to vendor that.
|
| The only reason you can even still control TLS 1.2 cipher
| suites is because of the fact that it might sometimes still be
| useful for legacy reasons to enable known-broken ciphers.
| There's really no other logical reason to keep that option.
| tptacek wrote:
| The only people who are being encouraged to fork crypto/tls are
| people building TLS testing tools. Nobody is suggesting that
| people building ordinary applications should run a forked Go
| TLS.
| jeroenhd wrote:
| Honestly, this sounds like a terrible decision. Preventing bad
| decisions by ensuring that no dev ever needs to set the cipher
| order in the first place would be a good idea, but ignoring flags
| and removing developer control because Google Knows Best is a
| terrible idea.
| Ajef wrote:
| It's open source. If you are capable of making such decisions
| on encryption with founded confidence you can also vendor the
| library and adapt it.
|
| The reality is most developers (almost every developer I know)
| won't spend particularly much time on deciding settings for
| encryption - and honestly if they spent 10x the amount they did
| doing research they would still only base their opinions on
| things they find online like blog posts (not mathematics or
| government whitepapers).
|
| I don't believe the approach is bad. It doesn't take the
| ability away from you to choose. It just adds a hurdle
| (vendoring the library), which imo stops a lot of bad decisions
| from overconfident developers.
|
| [edit]: typo
| [deleted]
| slownews45 wrote:
| Sounds like game over for google.
|
| That said, there is trend even outside of google to move away
| from high levels of configurability in these sort of security
| sensitive areas. I'd be curious what a system like wireguard
| lets you do in terms of bit twiddling.
|
| OpenSSL was sort of famous for letting your turn just about
| every knob you wanted. Not sure that was a ton better.
|
| And I have heard some concern that folks like apple put so much
| into attack surface on things like imessage (memoji's?) for
| messages from unknown and untrusted users (ie, new users you
| aren't texting with can send entire set of stuff imessage
| supports which is a TON vs just being text only to start). So
| even in other areas dialing down things might be helpful.
| tssva wrote:
| "I'd be curious what a system like wireguard lets you do in
| terms of bit twiddling."
|
| WireGuard doesn't allow you to do anything in terms of bit
| twiddling. This is one of the claimed benefits of WireGuard
| over OpenVPN or IPsec.
| tptacek wrote:
| To pile on: WireGuard doesn't even _have_ ciphersuites,
| exactly because of the arguments Filippo makes in this
| post. You get Curve25519 and ChaPoly, and that 's it.
| slownews45 wrote:
| Is it clear that then that as OP says this is a terrible
| idea?
|
| It seems then in keeping with ideas being followed
| elsewhere.
|
| Casually (not a security expert) this makes a let of
| sense to me. If I'm copying my stack overflow code out
| for my security stuff, maybe have fewer footguns?
|
| Not sure this is a terrible idea then.
| tptacek wrote:
| You should do whatever Filippo says you should do. Not
| trying to be flippant. :)
| jeroenhd wrote:
| I agree with Google that applications shouldn't normally be
| setting these parameters manually and I agree with their
| chosen defaults, but if developers are going through the
| effort of setting these values they're clearly doing it for a
| reason.
|
| That reason could be "the API doesn't allow developers to
| easily access the defaults" but the fix for that would be
| something completely different.
|
| Even in OpenSSL you don't get that much choice in TLS 1.3
| because the number of usable ciphers and key exchange methods
| has been severely reduced.
| [deleted]
___________________________________________________________________
(page generated 2021-09-15 23:00 UTC)