简体   繁体   中英

Allow all SSL protocols for node.js HTTPS request

Is it possible to make node.js https.request (client) negotiate any possible protocol (even if insecure) with remote servers? I understand the security risk, but for my project some websites only work with older/insecure SSL protocols & ciphers.

For example: https://www.dot.ny.gov doesn't work (timeout) with curl or latest node.js 7.10.1 default configuration on Ubuntu Server 16.04. It only works with curl using the --tlsv1.0 or --sslv3 options.

So is there a way to make node.js renegotiate the SSL connection using a range of protocols (from most secure to least secure), or use the widest possible configuration (either through node.js or underlying OpenSSL) to enable all SSL protocols & ciphers?

Just allowing these protocols will not fix the problem you describe with the site. TLS is by design mostly backward compatible, ie a properly implemented server which can only do SSL 3.0 or TLS 1.0 will just reply with the best protocol supported if confronted with a ClientHello from a client supporting TLS 1.2. This is because the client just announces the best version it can and the server then picks the best version it supports which is equal or less than the version offered by the client. Only then the "allow" comes into place, ie if the client will accept the reply by the server with the lower version.

But this is not the problem with the site you show. In this case the server or some middlebox in front of it has a buggy SSL/TLS stack which simply croaks on unexpected ClientHello. These might be a ClientHello which has an unexpected TLS version, unexpected extensions, unexpected ciphers, which are too small or too large or similar peculiarities.

In this specific case the TLS protocol version does not seem to be the problem at all but it looks more like the size of the ClientHello is a problem maybe because there is an old F5 load balancer with this bug in front of it. Since browsers tend to offer only a few ciphers their ClientHello is most times small enough to be not affected by this problem. For example if you try with a reduced cipher set as in openssl s_client -connect www.dot.ny.gov:443 -cipher 'AES128-SHA' you will succeed even with a TLS 1.2 ClientHello but if you try a larger one (like -cipher 'AES' ) it will just hang without getting a response back, probably because the broken load balancer croaked on the large ClientHello. And with enforcing TLS 1.0 in your command line you've just made sure that it does not offer also the new TLS 1.2 ciphers which also reduced the size of the ClientHello.

There is no general way to deal with such broken servers by just allowing everything because parts of the "allow" only comes after the server replied (which it does not in this case) and some actually might cause even more problems with the server (like offering too much ciphers which increases the size of the ClientHello). Instead one has to debug the problem, find out what the broken server likes and what it hates and then design a specific TLS handshake (version, ciphers, extensions, size...) so that the server likes it. And a good way to find out about what the specific server accepts is to look at the analysis by SSLLabs .

One of the most popular NPM packages for making HTTP(S) requests is request . According to its documentation you're able to specify what SSL protocols you want to accept.

If you know ahead of time what sites you're going to visit and what protocol they use you could set it per request. Otherwise I imagine you could write some conditionals although the overhead of making multiple requests would be cumbersome.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM