user2128702
user2128702

Reputation: 2121

Firebase function using node fetch returns certificate error

I have a firebase function which is running under Node.js 8 on a Pay-as-you-go Blaze plan. It is quite simple. It just uses node-fetch in order to execute an HTTP request:

   fetch(`https://api.thinger.io/v2/users/${accountId}/devices/${deviceId}/${resourceId}`, {
        method: 'post',
        body:    JSON.stringify({ "in" : true }),
        headers: { 
            'Content-Type': 'application/json;charset=UTF-8',
            'Authorization': `Bearer ${functions.config().thinger.devices_access_token}`
        },
    })
    .catch(err => console.error(err));

What I basically try to do here is to call Thinger.io's devices API. After the call gets executed I am getting the following error (which doesn't reproduce if I am using Postman, for example, in order to create the HTTP request)

{ FetchError: request to https://api.thinger.io/v2/users/*****/devices/*****/frontDoorRelay failed, reason: certificate has expired
    at ClientRequest.<anonymous> (/srv/node_modules/node-fetch/lib/index.js:1455:11)
    at emitOne (events.js:116:13)
    at ClientRequest.emit (events.js:211:7)
    at TLSSocket.socketErrorListener (_http_client.js:401:9)
    at emitOne (events.js:116:13)
    at TLSSocket.emit (events.js:211:7)
    at emitErrorNT (internal/streams/destroy.js:66:8)
    at _combinedTickCallback (internal/process/next_tick.js:139:11)
    at process._tickDomainCallback (internal/process/next_tick.js:219:9)
  message: 'request to https://api.thinger.io/v2/users/*****/devices/*****/frontDoorRelay failed, reason: certificate has expired',
  type: 'system',
  errno: 'CERT_HAS_EXPIRED',
  code: 'CERT_HAS_EXPIRED' } 

So, it is a bit hard for me now to diagnose if this is a firebase issue or node-fetch issue or something else. For sure, it is not Thinger.io issue because as I told you, if I create the request from another HTTP client (e.g. Postman) it works as expected.

NOTE: There's something that I want to mention here. There hasn't been any code base changes. It started to fail at a certain point just like that.

NOTE: If I try to create another HTTP request using node-fetch it works as expected:

fetch('https://api.github.com/users/github')
    .then(res => res.json())
    .then(json => console.log(json));

Upvotes: 0

Views: 1038

Answers (2)

Alvaro Luis Bustamante
Alvaro Luis Bustamante

Reputation: 8432

The problem is that one of the certificates in the chain, the root certificate, expired on 30 May 2020, as analyzed by https://www.ssllabs.com/:

SSL Certificate chain

It seems that some clients fail on this condition, even when the root certificate provided in the chain is not really used, as stated in the RFC5246:

"Because certificate validation requires that root keys be distributed independently, the self-signed certificate that specifies the root certificate authority MAY be omitted from the chain, under the assumption that the remote end must already possess it in order to validate it in any case".

I have fixed the certificate chain now, so, you should not have more problems related with SSL.

Upvotes: 0

user2128702
user2128702

Reputation: 2121

The solution for me was to update Node.js version from 8 to 10. Then, everything started to work as expected.

I followed this migration manual by Doug Stevenson. But, anyways, I think this issue needs to be further addressed by the Firebase team.

Upvotes: 1

Related Questions