quanguyen
quanguyen

Reputation: 1463

nodejs - certificate has expired

In my nodejs code, I request to a site using request library:

const httpReq = require("request")
function postJSON(uri, data, headers) {
  if (uri.slice(-1) != "/") {
    uri += "/"
  }

  console.log(`[postJSON] uri: ${uri}`)
  console.log(`[postJSON] body: ${JSON.stringify(data, null, 2)}`)
  console.log("[postJSON] headers", JSON.stringify(headers, null, 2))

  return new Promise((resolve, reject) => {
    httpReq(
      {
        method: "POST",
        uri: uri + Math.floor(Math.random() * 100000000).toString(),
        headers: headers,
        json: data
      }, function (err, resp, body) {
        console.log(`[postJSON] done with error: ${err} -> ${uri}`)

        if (err) {
          reject(err)
        }
        else {
          resolve(body)
        }
      }
    )
  })
}

For ~30 recent hours, my NodeJS code has got this issue:

unhandledRejection at: Promise  Promise {
  <rejected> { Error: certificate has expired
    at TLSSocket.<anonymous> (_tls_wrap.js:1108:38)
    at emitNone (events.js:105:13)
    at TLSSocket.emit (events.js:207:7)
    at TLSSocket._finishInit (_tls_wrap.js:638:8)
    at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:468:38) code: 'CERT_HAS_EXPIRED' } } reason:  { Error: certificate has expired
    at TLSSocket.<anonymous> (_tls_wrap.js:1108:38)
    at emitNone (events.js:105:13)
    at TLSSocket.emit (events.js:207:7)
    at TLSSocket._finishInit (_tls_wrap.js:638:8)
    at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:468:38) code: 'CERT_HAS_EXPIRED' }

I checked: Certificate of the endpoint (which is https://...) by opening Safari, accessing endpoint, and confirming the certificate expired data is ~Apr, 2021

I also tried to request the endpoint using curl and axios library from my server (the same location as my original nodejs code), the error is still thrown as above. I tried to request from my local machine, using the same code. It works!

So, there could be some difference between requests from my server and those from my local machine.

What could possibly cause this issue? How should I fix this?

As a temporary solution, I add this: process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'

Thanks

Upvotes: 5

Views: 20537

Answers (1)

user1817188
user1817188

Reputation: 517

In https://support.sectigo.com/Com_KnowledgeDetailPage?Id=kA03l00000117LT it state modern browser will have the modern USERTRust root so that the outdated AddTrust External CA Root will not be used to verify.

So, for node code, I try to test different node version, hope that new node version will do something like new browser to update to the modern USERTRust root

The test code is quite simple

const axios = require('axios');

axios.get('https://some.site.use.addtrust.external.ca.root')
  .then(function (response) {
    console.log(response.data);
  })
  .catch(function (error) {
    console.log(error.message);
  })

I tested all the 4 cases shown here: http://testsites.test.certificatetest.com/

Result shows that for the first 3 cases, nodejs version affects nothing. However, for the 4th case, node 10+ seems can fix the issue.

Here is the result:

  • lts/carbon -> v8.17.0 (certificate has expired)
  • lts/dubnium -> v10.20.1 (ok)
  • lts/erbium -> v12.17.0 (ok)

I test it on my mac Catalina 10.15.5

It appears that use node version 10+ can solve this issue for Certificate issued from a CA signed by USERTrust RSA Certification Authority with a cross cert via server chain from AddTrust External CA Root.

Upvotes: 6

Related Questions