Petros Kyriakoupersonal blog

I am a full stack web developer. Love tinkering all the time, especially anything javascript related.

How to specify a TLS version in node and a weird case with Stripe Webhooks

July 12, 2019

For the last week or so I was in constant contact with Stripe, trying to figure out why Stripe Webhooks always failed on my production server. The only breadcrump I had at the time is that my host was "unreachable".

So, the first thing I did was do my own POST request to my production server see how it behaves. And it was, reachable. Grown out of patience trying to figure out why; since the test webhooks worked, I contacted Stripe support.

The culprit

After back and forth with Stripe Support, a member of the support suggested that I add the production endpoint to the test mode and trigger test webhook requests from there.

Okay sure, lets do that, I said. I added the production server webhook endpoint and triggered a webhook test. And, it failed. Again. But this time, I had a more meaningful error message.

tls failure

Okay, not exactly clear but at least it didn't say unreachable. I was still buffled because I had an SSL certificate setup and working. A few hours later and a hundred google links later, I found a page where it said that Stripe only supports TLS v1.2 and up.

Still, it did not click with me as I assumed that my server would support that out of the box being in almost the latest node version and TLS v1.2 was one year old already.

SSL analysis

To see what versions of TLS my server supported I had to use some tools. I found two helpful web tools that helped bring clarity to this "madness".

For your convenience

https://www.cdn77.com/tls-test
https://www.immuniweb.com/ssl/

The first one gives exactly what versions of SSL/TLS your web server supports. The second one does a more expanded analysis on the SSL certificate.

The solution

OK, now I know that my server does not support TLS v1.2 but rather v1.0 - which is old, full of holes and in immediate need of stop using it. So, now it was time to dig into how to force TLS v1.2 and give up support for the last versions.

See the solution below:

https.createServer(
    {
     ...
      secureProtocol: 'TLSv1_2_method',
      secureOptions: constants.SSL_OP_NO_TLSv1_0
    },
    ...
  )

Whats of interest in the piece of code above, is the assignment in the options object when creating the HTTPS server, of secureProtocol and secureOptions. secureProtocol is what forces TLSv1.2 and secureOptions is what disables - in this case TLSv1.0.

Caveat: You need to check the support from browser of TLS v1.2 and if it is okay with your target audience. You can do that here

Note: If you search a bit you will see that TLSv1.3 is out already but according to IBM developer its not yet here for NodeJS.

Conclusion

And that was it folks, after days of going back and forth with Stripe support and a lot of reading I was able to fix the issues with Stripe webhooks. Whew...!