Sachin Jain
Sachin Jain

Reputation: 21842

Error: CERT_HAS_EXPIRED in Node.js request module (macu vs facebook)

My WebProxy is built in node. I am using request module to fetch content from given Url. I am getting CERT_HAS_EXPIRED error for https://www.macu.com while the site opens fine in browser.

My Investigations

I investigated and checked the certificate details via Chrome but I see that certificate is not expired. I do not understand the issue with this website's certificate.

I thought this could be an issue with the vendor not present in the list of Node.js. I tried upgrading npm and node versions but no success. Moreover https://www.facebook.com's certificate is also issued by DigiCert High Assurance CA-3 vendor which clearly says that this vendor is present in Node.js CA list.

Here is the code:

var request = require('request');

function getContent(urlOptions) {
  request.get(urlOptions, function(error, response, body) {
    if (error) console.log('Error:'  + error);

    if (body) {
      console.log('Body:' + body);
    }
  });
}

exports.init = function() {
  var urlOptions = {
    headers: {
      'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
      'Accept-Encoding': 'gzip,deflate,sdch',
      'Accept-Language': 'en-US,en;q=0.8',
      'Cache-Control': 'max-age=0',
      'Connection': 'keep-alive',
      'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.152 Safari/537.36'
    },
    secureProtocol: 'TLSv1_method'
  };

  /* URL options for macu.com domain */
  urlOptions.url = 'https://www.macu.com/mystyle-checking';
  urlOptions.headers.host = urlOptions.headers.Host = 'www.macu.com';
  // urlOptions.rejectUnauthorized = false;  // Works when this option is set but it may cause security issue

  getContent(urlOptions);

  urlOptions.url = 'https://www.facebook.com';
  urlOptions.headers.host = urlOptions.headers.Host = 'www.facebook.com';

  getContent(urlOptions);
};

I just want to know

  1. Why Request module complains for macu.com but not for facebook.com while both have certificates by same vendor.
  2. What is the issue with macu's certificate ?
  3. Why certificate is throwing error for node but is accepted by browser.

Upvotes: 2

Views: 8036

Answers (1)

C3roe
C3roe

Reputation: 96454

Your intermediate certificate for DigiCert High Assurance EV Root CA seems to have expired, see f.e. https://www.sslshopper.com/ssl-checker.html#hostname=www.macu.com

Likely your browser did not complain about it, because it had a newer, valid version of that intermediate cert installed already (and used that to prove the identity of the signing institution), whereas on your node instance it was still the old one (and it presented that to the counterpart).

Edit: A little further explanation: When an encrypted connection is negotiated between two parties, the initiating party will present its certificate and the intermediate certificates, so that the counterpart can verify them.

If your browser already has the up-to-date intermediate certificate DigiCert High Assurance EV Root CA stored in its own certificate cache, then it will likely use that to verify the certificate it is presented with.

Other parties (like your node.js module) however might not have the intermediate certificates stored themselves, so they rely on what they get presented. And if one of the certificates in the chain is expired, validation of the whole thing will therefor fail.

Upvotes: 2

Related Questions