NODE_TLS_REJECT_UNAUTHORIZED Heroku App making whole app insecure

Viewed 2547

I have an app on Heroku that uses a paid dyno and thus uses their ACM Automated Certificate Management

This should ensure all traffic between clients and the app are encrypted.

However, my app makes callouts to a separate private API. I'm awaiting a separate self-signed certificate just to be able to connect to this API (so this should all be separate from the Heroku cert). As a temporary workaround..all connections to this API are currently used with

process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';

I've read about the dangers of this and how to makes all of node unencrypted. My question is if the app is still secure when clients connect to the Heroku instance for other parts of the app not involving the API callouts. Or does setting that env var really make the whole app insecure regardless of the Heroku cert?

Thanks!

1 Answers

If I'm understanding you correctly, you have both incoming and outgoing connections, and your outbound connections to the API are using NODE_TLS_REJECT_UNAUTHORIZED.

Clients --in--> Your Application --out--> API

Your clients connection inbound to your application will still be GREEN and secure, but your outbound connections to the API will still be vulnerable.

Much like a chain, it is only as strong as its weakest link. So if someone were to attack your outbound connection to the API, they could receive all the datas.

You have two methods of solving this:

  1. Get a "real" certificate for the API.
  2. "Pre-authorize" the self-signed API certificate.

You can download the public key of the self-signed certificate and store it in your NodeJS app. Then, in your request, just add:

ca: [fs.readFileSync([certificate path], {encoding: 'utf-8'})]

This solution allows you to specify the CA certificate that you EXPECT. Make sure that the common name of the certificate is identical to the address you called in the request (as specified in the host):

var req = https.request({ 
      host: '192.168.1.1', 
      port: 443,
      path: '/',
      ca: [fs.readFileSync([certificate path], {encoding: 'utf-8'})],
      method: 'GET',
      rejectUnauthorized: true,
      requestCert: true,
      agent: false
    },

This method is MUCH more secure than just blindly setting "Accept all unknown people." This way is saying "John isn't certified, but I know John, and that's John. Just accept John."

Related