5

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

quanguyen
  • 1,443
  • 3
  • 17
  • 29
  • I wonder if the server (being in a different place on the internet) is getting routed to a different physical target server than when you make the request from your local computer. You could log the IP addresses of the target host from both places in case it's different, though that still might not tell the whole story because of proxies/load balancers/etc... – jfriend00 Jun 01 '20 at 09:03
  • 1
    solution found here : worked for me, node.js trying to talk to broken cert chain on backend. https://stackoverflow.com/questions/62107431/curl-error-60-ssl-certificate-problem-certificate-has-expired/62108103#62108103 , i used the fix at https://whatsmychaincert.com . Way to go Sectigo ... one more customer lost forevah ! – YvesLeBorg Jun 01 '20 at 13:06
  • Probably related to https://stackoverflow.com/questions/62107565/wget-and-curl-stopped-working-with-https-wrongly-complain-about-an-expired-cert I'm not sure what the solution is yet. I have it fixed in the OS (wget is happy), but no luck on my node code either, at the moment. I would have posted this as a comment, but I don't have enough reputation to. – Yamix Jun 01 '20 at 10:56

1 Answers1

6

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.

user1817188
  • 487
  • 1
  • 7
  • 14