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

OpenSSL issue: "unsafe legacy renegotiation disabled" #4543

Closed
1 task done
RobertKlohr opened this issue Mar 4, 2022 · 21 comments
Closed
1 task done

OpenSSL issue: "unsafe legacy renegotiation disabled" #4543

RobertKlohr opened this issue Mar 4, 2022 · 21 comments
Labels
B-bug Bug: general classification S-unverified Status: Unverified by maintainer

Comments

@RobertKlohr
Copy link

RobertKlohr commented Mar 4, 2022

Expected Behavior

Authenticate to API endpoint.

Timeline

* Preparing request to https://company-sandbox.keylightgrc.com:4443/SecurityService/Login
* Current time is 2022-03-04T04:08:35.352Z
* Using libcurl/7.73.0-DEV OpenSSL/1.1.1g zlib/1.2.11 brotli/1.0.9 WinIDN libssh2/1.9.0_DEV nghttp2/1.41.0
* Using default HTTP version
* Disable timeout
* Disable automatic URL encoding
* Disable SSL validation
* Disable cookie sending due to user setting
*   Trying 131.226.194.22:4443...
* Connected to company-sandbox.keylightgrc.com (131.226.194.22) port 4443 (#1)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*  CAfile: C:\Users\userid\AppData\Local\Temp\insomnia_2021.7.2\ca-certs.pem
*  CApath: none
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server did not agree to a protocol
* Server certificate:
*  subject: OU=Domain Control Validated; CN=*.keylightgrc.com
*  start date: May 31 13:52:12 2021 GMT
*  expire date: Jul  2 13:52:12 2022 GMT
*  issuer: C=US; ST=Arizona; L=Scottsdale; O=GoDaddy.com, Inc.; OU=http://certs.godaddy.com/repository/; CN=Go Daddy Secure Certificate Authority - G2
*  SSL certificate verify ok.

Actual Behavior

Timeline

* Preparing request to https://company-sandbox.keylightgrc.com:4443/SecurityService/Login
* Current time is 2022-03-04T04:18:18.407Z
* Using libcurl/7.79.1-DEV OpenSSL/3.0.0 zlib/1.2.11 brotli/1.0.9 WinIDN libssh2/1.9.0_DEV nghttp2/1.45.1
* Using default HTTP version
* Disable timeout
* Disable automatic URL encoding
* Disable SSL validation
* Disable cookie sending due to user setting
*   Trying 131.226.194.22:4443...
* Connected to company-sandbox.keylightgrc.com (131.226.194.22) port 4443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
*  CAfile: C:\Users\userid\AppData\Local\Temp\1\insomnia_2022.1.0\ca-certs.pem
* TLSv1.0 (OUT), TLS header, Certificate Status (22):
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS header, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (OUT), TLS header, Unknown (21):
* TLSv1.2 (OUT), TLS alert, handshake failure (552):
* error:0A000152:SSL routines::unsafe legacy renegotiation disabled
* Closing connection 0

Reproduction Steps

No response

Is there an existing issue for this?

Additional Information

After upgrading to version 2022.1.0 Insomnia fails to connect. If I roll back to Insomnia version 2021.7.2 it works. The problem is most likely in openssl that was update to OpenSSL/3.0.0 in the 2022.1.0 build. None of the preference settings in the client override the new default OpenSSL behavior.

Insomnia Version

2022.1.0

What operating system are you using?

Windows

Operating System Version

Windows 10 Enterprise 19043.1526

Installation method

The original install is in the appdata directory, the upgrade to version 2022.1.0 was automatic

Last Known Working Insomnia version

2021.7.2

@RobertKlohr RobertKlohr added B-bug Bug: general classification S-unverified Status: Unverified by maintainer labels Mar 4, 2022
@wdawson wdawson added M-duplicate Marked: Duplicate of another issue and removed M-duplicate Marked: Duplicate of another issue labels Mar 4, 2022
@wdawson wdawson changed the title error:0A000152:SSL routines::unsafe legacy renegotiation disabled OpenSSL issue: "unsafe legacy renegotiation disabled" Mar 4, 2022
@wdawson wdawson mentioned this issue Mar 4, 2022
1 task
@wdawson
Copy link
Contributor

wdawson commented Mar 4, 2022

Thanks, @RobertKlohr we're taking a look

@wdawson
Copy link
Contributor

wdawson commented Mar 4, 2022

Alright, so after investigation this is related to an upgrade of Electron that we did to support Apple Silicon (M1), among other benefits. It looks like the way this uses curl on Windows, which in turn uses OpenSSL 3.0.0. From what we can tell, there would be two options that could potentially address this:

  1. fork curl, which is something we don't want to do. This would likely open a whole other can of worms that is not worth dealing with for us right now.
  2. change our networking stack to something that might support this. The problem is that we aren't sure if anything will handle this correctly in node or not and this will still take a ton of time and effort.

So, unfortunately, it looks like there's nothing we can really do about this right now. This issue stems from quite old vulnerabilities in SSL renegotiation. Our understanding is that if more modern servers are used, this issue shouldn't get hit. @RobertKlohr can you confirm if you're constrained by needing to support really old clients or for some other reason cannot update your server side? Or maybe you don't control the servers?

@RobertKlohr
Copy link
Author

RobertKlohr commented Mar 4, 2022

@wdawson I do not control the servers but I will be opening a bug with the server operators to address this on their end.

I don't have the expertise in building applications with dependent libraries, but in my limited research, it seems that there are options in OpenSSL that allow you to support insecure SSL renegotiation on legacy systems. I just don't have any idea if, or where these can be applied as they relate to Insomnia. Is this something that must be done inside Insomnia because the OpenSSL libraries are in the build, or could users edit a configuration or system variable to override the new OpenSSL defaults on their systems separate from the Insomnia client.

For those with OpenSSL knowledge, any help here would be appreciated.

@pkaminsky
Copy link

There must be a way to fix it without forking OpenSSL, that's a weird conclusion to leap to. Surely there's a way to change the way libcurl is used, if not in Insomnia then at the very least in Electron. Insomnia was nice while it lasted, but it's unusable if there isn't a way to ignore the SSL errors.

@wdawson
Copy link
Contributor

wdawson commented Mar 8, 2022

I've gone through the various SSL and TLS CurlOptions but I can't seem to find anything related to this issue. Maybe I'm missing something? I believe Insomnia's networking stack is decoupled from the Electron networking controls, but could be wrong.

@johnwchadwick
Copy link
Contributor

@pkaminsky

There must be a way to fix it without forking OpenSSL, that's a weird conclusion to leap to. Surely there's a way to change the way libcurl is used, if not in Insomnia then at the very least in Electron.

More specifically, it is likely curl that we would have to fork. OpenSSL does provide a configuration option, SSL_OP_ALLOW_CLIENT_RENEGOTIATION, but we don't have direct access to set this option when using curl. One way we might be able to work around this problem is by using CURLOPT_SSL_CTX_FUNCTION to get a handle to the OpenSSL context. However, it definitely depends on how early into the handshake we get that call; and also, it is something that needs to be done inside of node-libcurl. It's not 100% clear that this approach will work, though it seems to be one of the more promising ones.

Insomnia was nice while it lasted, but it's unusable if there isn't a way to ignore the SSL errors.

Of course, it's never our intent to break existing setups outside of planned deprecation; in this case, it merely happened as a result of updating some of our dependencies. This is unfortunate and certainly not ideal.

However, it does seem that in the longer term, the TLS ecosystem is moving away from tolerating this insecure configuration. This is not without cause, of course, as many old TLS client and server configurations are rejected by modern TLS libraries. After all, the CVE associated with this now-default flag is from 2009 (CVE-2009-3555).

As time goes on, as OpenSSL 3.0 makes it into more software, and as other TLS libraries eventually follow suit, it seems likely that this server configuration will continue to lose support in more applications. The majority of servers will not have any issues since OpenSSL introduced support for TLS Renegotiation Extension in 0.9.8l, released in 2009, along with other TLS implementations. It is very likely that any server you are connecting to does have support for RFC 5746 and it is, for one reason or another, explicitly disabled.

Therefore, even if we are able to release a workaround, it is still highly recommended to escalate this issue on the end of the server operators, as it is unlikely to go away any time soon.

@STiAT
Copy link

STiAT commented Mar 10, 2022

In a coroprate environment this is a little bit of an issue, especially since the default option for NetScaler is on deny all reneg (should be on deny-insecure in my opinion?).

Can be worked around, but it probably will lead to issues for a few corporate users. Just to let people know, it's a NetScaler option you've to turn and probably not actually the web server behind that. Setting NetScaler from deny-all-reneg to deny-insecure actually makes it work again (at least in our test environment).

@ghost
Copy link

ghost commented Mar 21, 2022

I am getting the same issue since version 2022.2.0. How do I revert to a previous version, because now Insomnia is completely unusable on all destination APIs.

@ghost
Copy link

ghost commented Mar 21, 2022

Resolved by reverting to 2021.7.2

@ramvem
Copy link

ramvem commented Mar 22, 2022

In case others are interested Insomnia's website links to GitHub for downloading older releases -- Kong GitHub Insomnia releases. As mentioned by @kevrl you can get past the issue by downgrading to 2021.7.2. That worked for me.

@johnwchadwick
Copy link
Contributor

We've got a workaround for the issue in the works over at #4659. It took a bit longer than we were hoping due to some complexity with OpenSSL linking with node-libcurl, but we hope to ship it in a beta in the near future.

screenshot showing a new insomnia build that allows unsafe legacy renegotiation

Because I did not have a server setup that reproduced this issue readily available, I reproduced the issue using a modified version of the Go TLS stack. We're relatively sure that this should fix the issue, but obviously it's impossible to know for sure before it's released and working for everyone.

I'll try to remember to update this thread when we ship a beta release containing the patch.

@ajhalme
Copy link

ajhalme commented Apr 8, 2022

I was hitting this issue with some AWS ALB enpoints. Can confirm that the issue is fixed for me in Insomnia 2022.3.0-beta.3.

Thanks for the workaround. I appreciate the quick diagnosis as well.

@RobertKlohr
Copy link
Author

@johnwchadwick, I am really impressed that you were able to figure out a workaround so quickly, I know this must not have been easy, thanks!.

This should buy us a bit of time as it relates to any API endpoints where this is an issue. That said we should all be testing and contacting any endpoint owners where this is happening and get them to to fix their configurations.

For those reading this thread I wanted to add that based of the information @STiAT posted, I contacted the owners of the 3 endpoints where I had an issue, I know it is a small data set, but 100% of of the issues were due to ether a firewall or load balancer that was in front of the API endpoint and not the actual API endpoint servers. In all cases it was a configuration change that after being reviewed and going through the necessary change control was approved to be changed. I even go a big "Thank you" from one of the vendors for finding and passing this information along so they could fix it.

@RobertKlohr
Copy link
Author

@johnwchadwick I also confirm that 2022.3.0-beta.3 fixed this issue.

Is the intent to provide a setting in the configuration to toggle the workaround?

That capability would be helpful in the same way we can currently toggle the "Validate certificates during authentication" setting e.g., we can test when a server is configured correctly and bypass any configuration issues as necessary in legacy or development environments.

@johnwchadwick
Copy link
Contributor

@RobertKlohr
I'm glad to hear the patch is working. We can keep the issue open as a marker for adding a toggle. There are two reasons I did not make it a toggle so far:

  • Consistency. Not all platforms currently compile with the relatively-new OpenSSL 3.0, where this behavior was made default in the first place. As far as I know, we currently only have OpenSSL 3.x on Windows. Simply disabling it indiscriminately brings us back to where we were and are on other platforms.
  • False positives. Though this OpenSSL feature is well-meant and will probably catch some bad configurations in the wild, it's a little unreliable. A lot of TLS implementations don't seem to allow renegotiation at all anymore, and in this case it is a moot point whether or not the TLS renegotiation indication extension is present. As far as I can ascertain, for example, it appears that the Go TLS stack never supported renegotiation, but still supports the renegotiation indicator extension so that it won't be seen as "insecure." A client can't really reliably tell if a server will reject renegotiation indiscriminately. I'm sure middleboxes make this situation more complicated as well.

(And perhaps a bit of laziness. It would've taken longer to add a configuration option and plumb it through. But, that's not really a big deal.)

If we do add a toggle to do this, it will likely be off by default for now. We never intentionally included it in a build, after all; it came from a series of innocent-looking updates. What I'd really like is if we could get a warning so that we could warn users it will break by default in a future version. That would've been ideal in the first place, had we known it was going to happen...

@egarson
Copy link

egarson commented May 14, 2022

Hello,
For those of you on Linux, there is a system-level workaround for this problem.
Edit /usr/lib/ssl/openssl.cnf and find the line, "providers = providers_sect".
Edit/add the following:


  [openssl_init]
  # providers = provider_sect  # commented out
  
  # added
  ssl_conf = ssl_sect
  
  # added
  [ssl_sect]
  system_default = system_default_sect
  
  # added
  [system_default_sect]
  Options = UnsafeLegacyRenegotiation
  
  # List of providers to load
  [provider_sect]
  default = default_sect

Note that UnsafeLegacyRenegotiation is a workaround, and should not be deployed to a production environment.
The solution to the problem is for the "offending" server to implement RFC 5746.

@GloriousWater
Copy link

In a coroprate environment this is a little bit of an issue, especially since the default option for NetScaler is on deny all reneg (should be on deny-insecure in my opinion?).

Can be worked around, but it probably will lead to issues for a few corporate users. Just to let people know, it's a NetScaler option you've to turn and probably not actually the web server behind that. Setting NetScaler from deny-all-reneg to deny-insecure actually makes it work again (at least in our test environment).

Just wanted to say thanks! This was exactly the issue from one of our providers. We upgraded our software doing API calls, that would then start renegotiating handshakes, and thus was blocked. Being able to pinpoint this potential issue made them able to solve it and update their settings very fast.

@discaddict
Copy link

Thanks for the work that you do keeping insomnia working.

I've read through this thread a few times and tried to figure out exactly what the applied fix was but I'm struggling. The reason that I'm trying to understand this is that we have another third party software product that is experiencing the same issue.

We have NetScaler LB set to deny all renegotiation and when tested with latest insomnia all works fine. When we installed the older versions we were able to reproduce the "unsafe legacy renegotiation disabled" message.

So whatever change was made to insomnia has allowed it to operate with NetScaler devices that are configured to deny-all-reneg but all the discussion is about working with devices that are not up to date for secure negotiation so I'm struggling to create a picture that I can present to the third party to resolve the issue with their product.

Is anyone able to comment on how the changes allow insomnia to connect to devices that have deny-all-reneg set?

@jcracknell
Copy link

@discaddict this occurs because denySSLReneg=ALL is broken for NetScalers in that the NetScaler will stop sending an empty renegotiation_info extension in its ServerHello in violation of RFC5746. The best working option appears to be FRONTEND_CLIENT. My suspicion is at one point this was implemented correctly, but was likely broken later in an invalid "fix", as to my knowledge there is no way to signal that renegotiation is disabled.

Here they appear to have forked node-libcurl and enabled SSL_OP_LEGACY_SERVER_CONNECT and SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION.

@discaddict
Copy link

@jcracknell thank you so much for that. Super helpful.

@mirekphd
Copy link

hey appear to have forked node-libcurl and enabled SSL_OP_LEGACY_SERVER_CONNECT and SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION.

It looks like only enabling the first one was strictly necessary (and safer):
https://bugzilla.redhat.com/show_bug.cgi?id=2077973#c7

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
B-bug Bug: general classification S-unverified Status: Unverified by maintainer
Projects
None yet
Development

No branches or pull requests