Cuz Cuz - 1 year ago 762
Node.js Question


OS: debian sid

Nodejs: v0.10.38

I have a request to a private service that use authentication:

var https = require('https');

var options = {
host: '',
path: '/accounts/' + '123323' + '/orders',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': 0,
'Authorization': 'Bearer ' + 'asdsdgcvxcvxcv'

var request = https.request(options, function (res) {

When i run the script, node throws this error:

throw er; // Unhandled 'error' event
at SecurePair.<anonymous> (tls.js:1381:32)
at SecurePair.emit (events.js:92:17)
at SecurePair.maybeInitFinished (tls.js:980:10)
at [as _read] (tls.js:472:13)
at (_stream_readable.js:341:10)
at EncryptedStream.write [as _write] (tls.js:369:25)
at doWrite (_stream_writable.js:226:10)
at writeOrBuffer (_stream_writable.js:216:5)
at EncryptedStream.Writable.write (_stream_writable.js:183:11)
at write (_stream_readable.js:602:24)

The same exact script worked well for months, and i'm sure the authentication is correct. Today is the first time i have this situation.

Which can be the cause for this error?

Answer Source

There is a reason for SSL. Besides other features, it authenticates that you are really communicating with the server identified by hostname. Otherwise your client software can be cheated by a Man-in-the-Middle attack.

First when anyone encounters this issue, they should update system root SSL certificates. In Debian they are contained in ca-certificates apt-get package.

If it doesn't help, the server probably uses an issuer certificate, which is not trusted by default worldwide PKI infrastructure. In this case the client should compare the certificate public key signature with a preshared value. This is known as "certificate pinning".

Specifically to your error, if it worked before, it is possible that the server certificate has expired. The server should renew it. As a temporary solution, you can turn off PKI validation by rejectUnauthorized option. However you should use it together with the pinning approach. In NodeJS, you can get the server certificate fingerprint from res.socket.getPeerCertificate().fingerprint.