Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Allow Legacy Renegotiation for NodeJs

The best way to solve this would be to update the SSL endpoint I'm trying to connect to but I don't have the ability too.

I'm trying to reach a SOAP endpoint (it's painful) for an application that is barily being maintained and thus probably won't be able to get the proper SSL patch.

It's sitting behind a proxy that is doing active SSL rewrites and could also be to blame for the error:


var request = require("request")
var soap = require("soap")
const fs = require('fs')

var specialRequest = request.defaults({
  ca: fs.readFileSync("rewrite-example.pem")
})

var options = { request: specialRequest }

const WSDL = "https://SSL-rewrite.example?wsdl"

soap.createClient(WSDL, options, function(err, client) {
        if(err) throw Error(err)
})    

Error:

Uncaught TypeError: req.then is not a function
    at HttpClient.request (../node_modules/soap/lib/http.js:191:13)
    at Object.open_wsdl (../node_modules/soap/lib/wsdl/index.js:1271:20)
    at openWsdl (../node_modules/soap/lib/soap.js:70:16)
    at ../node_modules/soap/lib/soap.js:48:13
    at _requestWSDL (../node_modules/soap/lib/soap.js:76:9)
    at Object.createClient (../node_modules/soap/lib/soap.js:94:5)
> Uncaught: Error: write EPROTO C017726B8C7F0000:error:0A000152:SSL routines:final_renegotiate:unsafe legacy renegotiation disabled:../deps/openssl/openssl/ssl/statem/extensions.c:908

From what I found here, it's possible to create a custom OpenSSL config file allowing unsafe legacy renegotiation. And using Node's --openssl-config flag, it should be possible to "ignore" the renegotiation. I've tried writing a custom config file as written in the first link and passing it in but with no avail.

This question has been asked before, though reverting to an older verision of Node would not be ideal.

What might be some other wasys to resolve this?

like image 610
BobserLuck Avatar asked Feb 16 '26 09:02

BobserLuck


2 Answers

As you already have found, this error is coming from CVE-2009-3555, this is IIS issue, so it even won't be ignored using node flags. Since node 17 or 18, they removed the OpenSSL option to accept legacy servers.

I think a better solution in your case is passing httpsAgent with the option. soap.js uses Axios as of v0.40.0 according to the readme, so you should set the request param like this:

const crypto = require('crypto')

const options = {
  request: axios.create({
      // axios options
      httpsAgent: new https.Agent({
        // for self signed you could also add
        // rejectUnauthorized: false,

        // allow legacy server
        secureOptions: crypto.constants.SSL_OP_LEGACY_SERVER_CONNECT,
      }),
    }),
  }

https.Agent's secureOptions is a numeric bitmask of the SSL_OP_* options.

like image 85
MadDocNC Avatar answered Feb 17 '26 21:02

MadDocNC


You can setup the global configuration for OpenSSL when executing node process:

node --openssl-config=./openssl.cnf
# or by ENV (thanks for Faisal Feroz)
OPENSSL_CONF=./openssl.cnf node

--openssl-config: Load an OpenSSL configuration file on startup.

where openssl.cnf can be like:

nodejs_conf = openssl_init

[openssl_init]
ssl_conf = ssl_sect

[ssl_sect]
system_default = system_default_sect

[system_default_sect]
Options = UnsafeLegacyRenegotiation

Using nodejs_conf is required, since it will avoid conflict with other configuration files, see --openssl-shared-config for more info.

... it is recommended to use a configuration section specific to Node.js which is nodejs_conf and is default when this option is not used.

like image 45
呂學洲 Avatar answered Feb 17 '26 23:02

呂學洲