nodejs - certificate has expired

11,010

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.

Share:
11,010
quanguyen
Author by

quanguyen

Updated on June 04, 2022

Comments

  • quanguyen
    quanguyen almost 2 years

    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