-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
cargo should force strong TLS 1.2 cipher suites to reduce downgrade attacks because crates.io offers many "weak" TLS 1.0-1.2 cipher suites #8113
Comments
Is this a request for cargo (belongs here) or for crates.io (belongs https://github.com/rust-lang/crates.io)? If it is for cargo, can you elaborate on what you would like to see changed? |
@Eh2406 I updated the issue, primarily to address your excellent question about httpssl-version.
I'd like a cargo option (client-side) in the [http] section similar to this:
If option is set to true, I'd like the resulting TLS cipher suite enabled by cargo match the screenshot provided under "Describe the solution you'd like".
If cargo specifies
So the recommended |
I updated the issue and title to incorporate excellent feedback received during |
We discussed this a bit and in general sounds like a good idea, with the following thoughts:
One of the big issues will be figuring out how to make all of the above work on the platforms we support. Presumably if we're running on a platform that doesn't support these strong restrictions, Cargo should probably fall back to some weaker stance. I fear that may be tricky. Would you be willing to help dig into how to support that for different platforms? Some rough notes about what we currently do:
|
@ehuss Thanks for looking into this!
I agree. My initial reasoning forgot our users are programmers and I tried to simplify to reduce user error (typos, using OpenSSL vs Schannel syntax, etc.) In rust-lang/rustup@59114b8 we added RUSTUP_TLS_CIPHERSUITES to rustup-init.sh and use it if it's not empty. Otherwise, we force strong TLS 1.2-1.3 cipher suites if support is detected and fall back to simple TLS 1.2 requirement if needed.
I agree it can get tricky, especially if it includes Schannel or old unsupported OS versions. Yes, I'd like to help. Experience includes replacing Schannel with stripped down OpenSSL and eventually LibreSSL (static linked because it auto-updated via TLS to linux/*bsd cloud). My software used TLS 1.2 ECDHE + AEAD (exclusively) on customer's Windows XP-7 clients and Windows 2008R2-2016 servers.
I think there are opportunities to simplify and increase reuse. MacOS: 10.14 has curl+LibreSSL with support for strong cipher suites. I barely know how to use MacOS (only used MacOS and Windows ~3 times this year). Windows: Schannel capabilities can vary too much (it can depend on whether it has certain updates, registry settings enabling some ciphers, etc.). 👉 curl's official binary for Windows is statically linked to OpenSSL 1.1.1f. What prevents us from replacing Schannel with statically linked OpenSSL 1.1.1g in cargo for Windows? Linux: Static linking to libcurl and OpenSSL sounds good to me, esp. if we're reasonably quick about updating OpenSSL with important security fixes. I think OpenSSL 1.0.1, 1.0.2, and 1.1.0 are EOL and were the first three versions to support TLS 1.2. Any version of OpenSSL with TLS 1.2 will support most or all of the strong cipher suites. When ready, we should ask package maintainers (if any) to test with desired strong cipher suites for compatibility. Other platforms: Maybe we can ask users requiring old/obscure platforms to run a simple compatibility-test program that uses cargo's libcurl+openssl file downloading API. The web server used for compatibility tests should be configured to log the TLS version, cipher suite, and user-agent. The test client should include client+platform version info in the user-agent. Example nginx server logging TLS version and cipher suite:
|
Schannel on Windows 7-8.1 doesn't appear to support ECDHE_RSA with AES_GCM according to The only two strong TLS 1.2 cipher suites offered by crates.io use ECDHE_RSA + AES_GCM. |
I ran some tests against badssl.com using curl and various bits of configuration. Looks like at least with respect to TLS versions we have good platform support. I believe the dynamically linked libcurl (at least recent versions on OSX) support selecting the protocol and denying previous versions. Statically linked OpenSSL works as expected and schannel appears to work too. For ciphersuite negotiation I was less certain to figure out how things were working. Looks like it's configured with OpenSSL, something is at least passed down for schannel, but "cipher_list" isn't mentioned anywhere in sectransp.c. On my mac Some things I've thought while looking into various pieces:
|
@alexcrichton just a quick FYI, there were 3 scenarios tested during TLS hardening for rustup-init.sh:
In the 3rd test, the client using hardened cipher suites (if supported) must ignore all the weak ones preferred by the server and use the first matching strong cipher suite. I only tested manually, but the server could probably be setup to provide TLS version and cipher suite in the https content or headers. |
Official curl binary for Windows uses OpenSSL 1.1.1f so we can avoid all the edge cases they already encountered and resolved. curl-rust and/or cargo can be compared with how curl does things on Windows. It may be useful for alexcrichton/curl-rust#284 to also look at curl+openssl provided by homebrew or macports to avoid known issues.
One way is to setup testing subdomains with nginx + Let's Encrypt certs:
For test 3, nginx can return TLS connection info in headers like this:
Which can be seen with:
A diagnostic client program using cargo's download function would be useful. It can print, send, and receive more detailed info than cargo during TLS connection tests. We can ask the rust community to run it on a variety of platform versions during development and when we're helping with any download issues for cargo & rustup (rust-lang/rustup#2294). |
@x448 would you be willing to help implement the changes necessary for this? I'd be curious to test this nginx setup for windows/mac/linux to see how we respond today and what the various capabilities are we have available to us. The example program I had above tests some things about bad certificates and such but unfortunately curl didn't have great introspection mechanisms for which TLS ciphers were in use. I can help out testing on platforms you don't have access to, but it'd be great for having something like a docker image with nginx running which prints out all the debug info about cargo connecting to it. |
Describe the problem you are trying to solve
crates.io is using servers that offer TLS 1.0, TLS 1.1, and TLS 1.2 with a numerous "weak" cipher suites enabled according to SSL Report.
The downgrade protection mechanism in TLS 1.2 relies on downgradeable parameters. So we should force TLS 1.2 to only allow strong cipher suites (reduce possible downgrade attacks).
cargo should add protection against TLS 1.2 downgrade attacks instead of relying solely on crates.io (vendors can change or make mistakes, etc. so a server-only fix isn't enough).
A similar issue was resolved in rustup-init.sh in rust-lang/rustup#2287 on April 22, 2020.
From EUROCRYPT 2016, Protecting TLS from Legacy Crypto (pdf, iacr.org):
(click to expand) 📷 SSL Report (Qualys) for crates.io
Describe the solution you'd like
cargo should force use of strong TLS 1.2 cipher suites (if supported by required libraries).
cargo can provide an [http] option to enable this (as opt-in, until there's enough confidence to make it the default behavior).
Ideally, I'd like to see the same 9 cipher suites as Firefox 68 ESR with all weak cipher suites disabled via
about:config
.(click to expand) 📷 SSL Client Test of Firefox 68 ESR (hardened)
Example of client-side OpenSSL cipher suites list tested with curl and wget
--ciphers
option:DHE is excluded from cipher suites because servers often use bad DH params (see RFC 7919).
Notes
(click to expand) Links to RFC and etc. about TLS
2008. TLS 1.2 was defined in RFC 5246 in August 2008.
2015. Imperfect Forward Secrecy: How Diffie-Hellman Fails in Practice (pdf, weakdh.org)
22nd ACM Conference on Computer and Communications Security (CCS ’15), Denver, CO, October 2015. Best Paper Award Winner.
2016. RFC 7919 Negotiated Finite Field Diffie-Hellman Ephemeral Parameters for Transport Layer Security (TLS).
2016. Protecting TLS from Legacy Crypto (pdf, iacr.org) KarthikeyanBhargavan+ many, many others.(INRIA, Microsoft Research, LORIA, IMDEA,Univof Pennsylvania, Univof Michigan, JHU)
2018. TLS 1.3 was defined in RFC 8446
The text was updated successfully, but these errors were encountered: