curl icon indicating copy to clipboard operation
curl copied to clipboard

Can't communicate when a server does not support secure renegotiation with OpenSSL 3.0.0 and above.

Open yoe opened this issue 2 years ago • 9 comments

I did this

curl -k https://old-host/

I expected the following

the result of the HTTP object

I got instead

curl: (35) error:0A000152:SSL routines::unsafe legacy renegotiation disabled

curl/libcurl version

curl 7.83.1 (x86_64-pc-linux-gnu) libcurl/7.83.1 OpenSSL/3.0.3 zlib/1.2.11 brotli/1.0.9 zstd/1.5.2 libidn2/2.3.2 libpsl/0.21.0 (+libidn2/2.3.0) libssh2/1.10.0 nghttp2/1.47.0 librtmp/2.3 OpenLDAP/2.5.12
Release-Date: 2022-05-11
Protocols: dict file ftp ftps gopher gophers http https imap imaps ldap ldaps mqtt pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp 
Features: alt-svc AsynchDNS brotli GSS-API HSTS HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM NTLM_WB PSL SPNEGO SSL TLS-SRP UnixSockets zstd

operating system

Debian GNU/Linux "unstable"

Notes

This is due to a change in OpenSSL 3.0.0, as documented here: in OpenSSL 3.0.0, the option SSL_OP_LEGACY_SERVER_CONNECT is no longer set by default, which it was in 1.1.1.

It would be good if curl had an option to set that OpenSSL option; I searched for "reneg" in the curl(1) man page, but did not find any.

yoe avatar May 31 '22 12:05 yoe

To me it sounds like you want SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION. Described here: https://www.openssl.org/docs/man3.0/man3/SSL_get_options.html

bagder avatar May 31 '22 12:05 bagder

I'm not convinced it is worth adding an option to curl just because there exist (a few) ancient leftover legacy servers that haven't upgraded. You can probably rebuild your curl yourself instead with that option set until they come to their senses and fix their installations. The are called unsafe for a reason.

bagder avatar Jun 04 '22 15:06 bagder

You can probably rebuild your curl yourself instead with that option set until they come to their senses and fix their installations.

FWIW, the context here is a Cisco Anyconnect VPN installation that uses it, and where my openconnect installation broke when my distribution's curl was upgraded to now be compiled against OpenSSL 3.0.0. Updating the csd-wrapper.sh script that ships with openconnect to use wget instead of curl "fixed" the issue (for now), but that's not great.

Additionally, while I could fix the issue more long-term by adding a patch like you suggest and then recompiling curl, for the same reasons that you point out it isn't necessarily a good idea to have a recompiled curl which sets that option for every connection I try to run, as opposed to just those servers which exhibit the problem (in casu, just one server for me). Hence the question to be able to only enable things in exceptional situations.

For the more permanent solution I could poke Cisco to update their TLS implementation in Anyconnect, I suppose, and I could then ask the IT people at $DAYJOB to please update their anyconnect version, but somehow that doesn't sound like a strategy that will result in a fix very quickly.

yoe avatar Jun 04 '22 22:06 yoe

Sorry but I agree with @bagder, this is the first I'm reading of it and I don't see enough use to add an option. You can of course fork curl and add the option yourself either directly in libcurl or use CURLOPT_SSL_CTX_FUNCTION and SSL_CTX_set_options.

jay avatar Jun 10 '22 04:06 jay

So, I'm guessing you guys haven't heard much of this yet because it's a fairly new change in OpenSSL. I suspect that once the change is more widespread, either servers will be updated (and then the issue will sort itself out), or you will get more requests for this ;-)

I'd suggest leaving this open until either of the above two happens, and then this can be revisited if necessary?

yoe avatar Jul 20 '22 09:07 yoe

If you or your distro upgrades to OpenSSL 3 then by default some older legacy algorithms and/or handshake methods may be disabled. OpenSSL 3 has been out for almost a year and we haven't heard much of anything about this issue, though someone filed a duplicate yesterday. I'm apt to close issues like this, we can't leave feature requests/ enhancements open, either someone is working on it if we plan on adding it or we close it.

jay avatar Jul 20 '22 14:07 jay

now stuck! versions before 7.84 have CVEs but 7.84 no longer functionally works due to this error

tooptoop4 avatar Jul 22 '22 03:07 tooptoop4

The latest curl can be built with older versions of OpenSSL.

edit: Seems I misunderstood. From the other issue he wants to use a pre-built version of curl. He could of course build the latest curl with the latest OpenSSL, with modifications to allow legacy renegotiation.

jay avatar Jul 22 '22 06:07 jay

we lazy, want da binaries. https://github.com/moparisthebest/static-curl/releases seems to have come to rescue here

tooptoop4 avatar Jul 27 '22 08:07 tooptoop4

We are not prepared to offer renegotiations as a (special OpenSSL) option now. We may reconsider if this hurts many more people or if other details change.

bagder avatar Aug 11 '22 09:08 bagder

refresh please

Mirocow avatar Sep 14 '22 22:09 Mirocow

I'm getting hit with this on a site that SSL Labs rates A+. A workaround here https://stackoverflow.com/questions/71603314/ssl-error-unsafe-legacy-renegotiation-disabled

ysiivan avatar Sep 28 '22 22:09 ysiivan

Also getting this with GlobalProtect VPN.

mrkkrp avatar Oct 17 '22 13:10 mrkkrp

i'm currently effected by this as well. i work for an enterprise company (a large one), and yea, they have outdated vpn technology. probably need to downgrade my curl version or rewrite csd-post.sh to use wget.

jsdevel avatar Feb 03 '23 17:02 jsdevel

As a workaround, I tested this config in openssl.conf; I don't use it on production yet, as I urge my partners to fix their crypto (and retain curl − in my case alpine − upgrade for now).

openssl_conf = openssl_init

[openssl_init]
ssl_conf = ssl_sect

[ssl_sect]
system_default = system_default_sect

[system_default_sect]
Options = UnsafeLegacyRenegotiation

sereinity avatar Feb 06 '23 09:02 sereinity

As a workaround, I tested this config in openssl.conf; I don't use it on production yet, as I urge my partners to fix their crypto (and retain curl − in my case alpine − upgrade for now).

openssl_conf = openssl_init

[openssl_init]
ssl_conf = ssl_sect

[ssl_sect]
system_default = system_default_sect

[system_default_sect]
Options = UnsafeLegacyRenegotiation

this worked for me too.

jsdevel avatar Apr 14 '23 16:04 jsdevel

This problem arose in my organization as they are using Cisco AnyConnect. I find it weird that I can browse the website https://vpn.######.org/CACHE/sdesktop/hostscan/linux_x64/manifest with Firefox but I cannot download the same with curl. This seems like a limitation of the software to me. Yes it might be insecure but I really would like to have an option to know what is contained in that file without having to use Firefox. Other users have suggested wget but I have the same problem with that:

$ curl https://vpn.######.org/CACHE/sdesktop/hostscan/linux_x64/manifest
curl: (35) OpenSSL/3.0.8: error:0A000152:SSL routines::unsafe legacy renegotiation disabled
$ echo $?
35
$ wget https://vpn.######.org/CACHE/sdesktop/hostscan/linux_x64/manifest
--2023-07-24 13:17:13--  https://vpn.######.org/CACHE/sdesktop/hostscan/linux_x64/manifest
Resolving vpn.######.org (vpn.######.org)... a.b.c.d
Connecting to vpn.######.org (vpn.######.org)|a.b.c.d|:443... connected.
OpenSSL: error:0A000152:SSL routines::unsafe legacy renegotiation disabled
Unable to establish SSL connection.
$ echo $?
4

freeseek avatar Jul 24 '23 17:07 freeseek

see https://github.com/curl/curl/issues/8943#issuecomment-1418735060 for one way to work around this

bagder avatar Jul 24 '23 17:07 bagder

An even cleaner workaround: echo -e "openssl_conf = openssl_init\n[openssl_init]\nssl_conf = ssl_sect\n[ssl_sect]\nsystem_default = system_default_sect\n[system_default_sect]\nOptions = UnsafeLegacyRenegotiation" | OPENSSL_CONF=/dev/stdin curl https://old-host/

freeseek avatar Jul 24 '23 17:07 freeseek

I can verify this occurs to current versions of curl (and wget) if the machine is connected to palo alto Global Protect VPN. I disconnect vpn and exact same commands work fine. My opinion is that it would be good/useful to specify an argument to the curl command to allow the connection. That way it can be selectively used by a user in this situation who knows why it's happening and is comfortable bypassing the security measure, per command run. A system config change that affects every run of the command makes the system less secure. I must include that I don't know if there is any setting that could be changed on the VPN side to fix this as I don't manage that and have no knowledge of it's options.

dcopenhaver avatar Jul 27 '23 19:07 dcopenhaver

We also ran into this issue, unfortunately since Curl doesn't support it, then their is no option we can pass in via php's bindings to libcurl, which then means afaik we have to implement this downgrade in security system wide rather than it being done on a single client's connection.

This would be nice to have in the libcurl so it could be exposed to php scripts using curl to connect to remote servers...

NathanaelA avatar Jul 31 '23 21:07 NathanaelA

@NathanaelA I don't think that's true. In https://github.com/curl/curl/issues/8943#issuecomment-1151942200, @jay suggested a way "anyone" can do it, so the PHP (or other) binding code could do this (maybe if a special option is set).

bagder avatar Jul 31 '23 21:07 bagder

I made #11559 as a test for how this could be supported.

bagder avatar Jul 31 '23 21:07 bagder

@NathanaelA I don't think that's true. In #8943 (comment), @jay suggested a way "anyone" can do it, so the PHP (or other) binding code could do this (maybe if a special option is set).

Yep, but then that requires a custom version of PHP compiled which adds a lot more work since php has new versions fairly frequently and we would rather not maintain them (and/or php_curl extension) on multiple servers for a single issue. If this was supported in libcurl, then even if php_curl doesn't have that flag yet, we can just pass in the flag value to setopts for that single client (so far that we have discovered) is now borked on the new openssl/curl/php version.

We are going to request our client upgrade their security and give them a week or so and then revert the config file change.

The only reason I added our info to this issue is just so you have feedback that not having a flag for a change has impacts in other areas not just the cli. It would have been nice if there was an easy way to disable it just for a single client instead of server wide...

NathanaelA avatar Jul 31 '23 22:07 NathanaelA

I made #11559 as a test for how this could be supported.

I didn't see this until today, and I see the PR was closed again already after only a week... 🤷

Thanks for considering this, regardless. Then again, $DAYJOB apparently did update the VPN in the mean time, and I no longer face this issue, so I have indeed list interest.

yoe avatar Sep 13 '23 13:09 yoe

Well just a small update, we actually ran into this with a massive number of clients and vendors, so both sides of the people we interface with, over the following weeks. We finally decided to just had to leave this security disabled server wide on all our servers because it was causing way too many issues.

I vote strongly for this to be implemented in libcurl, so that we could easily disable it per client and per vendor by using flag values as we do create custom override php scripts per vendor and per client for interfaces with their systems.

NathanaelA avatar Sep 13 '23 19:09 NathanaelA

I can't download any page from https://www.gigroup.it/ . Chrome can. I know what is the problem, I know it's a server issue, but Curl can get through with the right ssl parameter, parameter that Curl has not at the moment. I need a way to reach the site also if it is insecure in some way. I'm stucked.

GattoExpress999 avatar Oct 14 '23 19:10 GattoExpress999

I know what is the problem, I know it's a server issue, but Curl can get through with the right ssl parameter, parameter that Curl has not at the moment.

There are workarounds described in this issue. For example this one.

jay avatar Oct 14 '23 20:10 jay