Skip to content

openssl-legacy-provider CLI argument doesn't seem to work as expected #47379

Description

@lokesh411

Version

v18.15.0

Platform

5.4.0-1089-azure #94~18.04.1-Ubuntu SMP Fri Aug 5 12:34:50 UTC 2022 x86_64 GNU/Linux

Subsystem

No response

What steps will reproduce the bug?

I recently upgraded the service that i was working on from node:14 to node:18, I was getting the following error
write EPROTO C057DCF6287F0000:error:0A000152:SSL routines:final_renegotiate:unsafe legacy renegotiation disabled
When i investigated a bit, I found that in node:17 openssl was upgraded to 3.0.0, which resulted in removing the support for legacy cipher algorithms. And the workaround for the same was running with --openssl-legacy-provider.
I tried running with this and it didn't work. Can you please help me here?

How often does it reproduce? Is there a required condition?

No response

What is the expected behavior? Why is that the expected behavior?

As per the documentation, --openssl-legacy-provider should work and it should switch to the legacy provider of openssl 3.0.0. But i was still getting the same error

What do you see instead?

write EPROTO C057DCF6287F0000:error:0A000152:SSL routines:final_renegotiate:unsafe legacy renegotiation disabled

Additional information

I tried running the service/script with the following command. (app.js is the file name)
node --openssl-legacy-provider app.js tried also doing this node app.js --openssl-legacy-provider

Activity

  1. mscdex commented on Apr 3, 2023

    @mscdex
    Contributor

    --openssl-legacy-provider only enables insecure algorithms (e.g. ciphers, hashes, etc.). The error you're encountering is specifically about TLS/SSL.

    You can enable the unsafe legacy renegotiation by setting secureOptions: crypto.constants.SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION (or perhaps SSL_OP_LEGACY_SERVER_CONNECT) in your HTTPS request settings, but you really should not because it can open you up to man-in-the-middle attacks according to the related CVE-2009-3555. It's better to have the endpoint you're trying to connect to upgrade its TLS/SSL handling.

  2. lokesh411 commented on Apr 3, 2023

    @lokesh411
    Author

    Yes, I am also trying to upgrade the SSL cipher suites, but i would want to have a temporary workaround.
    I tried the securedOptions as well, that works, but i want to enable this globally.
    Is there anyway to use the unsafe legacy renegotiation globally in node:18, without any changes in the code base?

  3. mscdex commented on Apr 3, 2023

    @mscdex
    Contributor

    You should be able to set up an openssl.cnf that is configured appropriately and tell node to use that (e.g. setting the OPENSSL_CONF environment variable or passing the path on the command line via --openssl-config=...) for configuring OpenSSL's behavior.

  4. lokesh411 commented on Apr 3, 2023

    @lokesh411
    Author

    Understood, Thanks a lot for your time and information

  5. mikaello commented on Apr 14, 2023

    @mikaello

    I think the error unsafe legacy renegotiation disabled is hitting many users on VPN or behind corporate firewalls not supporting RFC5746 secure renegotiation, for those users it doesn't help that the remote server supports it.

    I have struggled a lot with this error, and in every case ended up downgrading to Node 16. I have tried both OPENSSL_CONF and NODE_OPTIONS='--openssl-config=...' for our applications, but it does not work. It seems like Node won't load the option defined in the provided config. This is the config I have used:

    openssl_conf = openssl_init
    
    [openssl_init]
    ssl_conf = ssl_sect
    
    [ssl_sect]
    system_default = system_default_sect
    
    [system_default_sect]
    Options = UnsafeLegacyServerConnect

    Since the option UnsafeLegacyServerConnect was unsupported in OpenSSL < 3.0.4, I have also tried the option UnsafeLegacyRenegotiation with no luck.

    If someone finds a solution, please write about it :-)

  6. ckcr4lyf commented on May 23, 2023

    @ckcr4lyf
    Contributor

    If someone finds a solution, please write about it :-)

    @mikaello you need to set the section name as nodejs_conf in the OpenSSL config file, introduced in #43124

    So for example, you could use the following:

    nodejs_conf = openssl_init
    
    [openssl_init]
    ssl_conf = ssl_sect
    
    [ssl_sect]
    system_default = system_default_sect
    
    [system_default_sect]
    Options = UnsafeLegacyRenegotiation
    

    I've a PoC w/ docker if its of interest: https://github.com/ckcr4lyf/no-rfc5746/blob/ed83a446e4aaa08f1edaa96af9b41c91b56834f5/Dockerfile

  7. stillcollating commented on Jun 14, 2023

    @stillcollating

    I have tried various combinations of all these settings on nodejs 18.16.0 windows x64, to no avail. I'm always getting "unsafe legacy renegotiation disabled". This is stemming from the transparent ssl proxy on my corporate network. I know I had this working awhile back (multiple months) on nodejs 18, and my notes only say to use --openssl-legacy-provider. Not sure if nodejs changed or our ssl snooper changed.

    Setting secureOptions to either SSL_OP_LEGACY_SERVER_CONNECT or SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION does fix the problem. But I'm trying to get npm to work, so I need a more global setting.

    When I use --openssl-config=xxxx I don't get any error even when I supply a nonexistent filename.. makes me wonder if this option is actually reading in the openssl.cnf I'm trying to give it. Tried both UnsafeLegacyRenegotiation and UnsafeLegacyServerConnect. Neither changed the behavior.

  8. ckcr4lyf commented on Jun 15, 2023

    @ckcr4lyf
    Contributor

    When I use --openssl-config=xxxx I don't get any error even when I supply a nonexistent filename..

    @stillcollating what is the command when you're trying to pass it as CLI to npm? I am not sure if passing it via, e.g.

    npm install abcd --openssl-config=xxxx
    

    I think npm won't pass those down to node itself.

    You can try and use the OPENSSL_CONF environment variable and see if that helps.

  9. ckcr4lyf commented on Jun 15, 2023

    @ckcr4lyf
    Contributor

    I know I had this working awhile back (multiple months) on nodejs 18

    Do you remember which version of 18? The behavior of the section in openssl.cnf was changed in 18.4.

  10. stillcollating commented on Jun 15, 2023

    @stillcollating

    @ckcr4lyf I've been doing my testing with just nodejs using a test.js that calls https.request. If I set secureOptions with SSL_OP_LEGACY_SERVER_CONNECT or SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION the https.request works. I just need that to be the default behavior in any call to https.request. the openssl-config setting seems the most likely solution but it is not work for me thus far.

    In windows command prompt I have been testing using: node --openssl-config=openssl.cnf test.js

    openssl.cnf and test.js are in current working directory.

    And test.js contains a call to https.request.

    no error is given with a nonexistent openssl.cnf and supplying a valid openssl.cnf file with the suggested settings does not fix the issue. I also tried setting OPENSSL_CONF environment variable and no luck.

    I get the feeling this is likely specific to the Windows version of node, but that's just a guess.

  11. ckcr4lyf commented on Jun 15, 2023

    @ckcr4lyf
    Contributor

    no error is given with a nonexistent openssl.cnf

    Right, it is silently ignored

    I get the feeling this is likely specific to the Windows version of node

    I think you might be right, I can't confirm this as I'm on Linux, but when I later get access to a Windows PC I'll try.

  12. RunSeven commented on Jul 28, 2023

    @RunSeven

    I had a similar issue on Windows using node 18.17.0 and npm 9.6.7

    I had some success using a variation on the above answers by @mikaello and @ckcr4lyf where either the last or first line is changed respectively.

    nodejs_conf = openssl_init
    
    [openssl_init]
    ssl_conf = ssl_sect
    
    [ssl_sect]
    system_default = system_default_sect
    
    [system_default_sect]
    Options = UnsafeLegacyServerConnect 
    
  13. liudonghua123 commented on Aug 30, 2023

    @liudonghua123
    Contributor

    I use export NODE_OPTIONS=--openssl-legacy-provider (linux/macos) or set NODE_OPTIONS=--openssl-legacy-provider (windows) for my node 18/20+.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions