Allan Martins
Allan Martins

Reputation: 862

Node-fetch: Disable SSL verification

I have the following code, which is run from a express server:

import fetch from 'node-fetch';

let formBody = [];

const dataLogin = {
      'username': 'myUser',
      'password': 'myPassword'
};

for (let p in dataLogin) {
   let encodedKey = encodeURIComponent(p);
   let encodedValue = encodeURIComponent(dataLogin[p]);
   formBody.push(encodedKey + "=" + encodedValue);
 }

 formBody = formBody.join("&");   

 const url = 'https://external-login-api.com';
 return fetch(url, {
          method: 'POST',
          headers: {
              'Content-Type': 'application/x-www-form-urlencoded',
              'Content-Length': formBody.length         
  },     
  body: formBody
 });

When I run the code I get the following error, despite being able to run the request in Postman with no problems.

{"message":"request to https://external-login-api.com failed, reason: write EPROTO 7316:error:141A318A:SSL routines:tls_process_ske_dhe:dh key too small:openssl\ssl\statem\statem_clnt.c:1472:\n","type":"system","errno":"EPROTO","code":"EPROTO"}

How do I disable SSL verification for this request?

Upvotes: 72

Views: 155729

Answers (4)

snicker
snicker

Reputation: 41

I'm surprised no one suggested using node's builtin fetch() with a simple customized Agent, combining some of the answers. The agent is provided by undici:

npm install undici

And then simply:

import { Agent } from 'undici'

export function fetchWithoutSSL(url, options) {
    const httpsAgent = new Agent({
        connect: {
            rejectUnauthorized: false
        }
    })

    return fetch(url, {
        ...options,
        dispatcher: httpsAgent
    });
}

This is tested to work with node 23.3.0.

The disadvantage of setting NODE_TLS_REJECT_UNAUTHORIZED or using setGlobalDispatcher() is that all usages of fetch() anywhere will then ignore SSL. And the disadvantage of Karthik's answer is that it requires the node-fetch package.

Upvotes: 0

Draex_
Draex_

Reputation: 3484

Node v20 - global configuration

  1. Add undici to your dependencies. (For me, it's a dev dependency, because I disable the verification only in dev environment.)
npm install --save-dev undici
  1. Add this code before you call fetch
import { Agent, setGlobalDispatcher } from 'undici'

const agent = new Agent({
  connect: {
    rejectUnauthorized: false
  }
})

setGlobalDispatcher(agent)
  1. Use fetch anywhere in your app
await fetch('...')

Upvotes: 8

Karthik
Karthik

Reputation: 2642

The other way to do is to set your own agent to the fetch call.

const fetch = require('node-fetch');
const https = require('https');

const httpsAgent = new https.Agent({
      rejectUnauthorized: false,
    });

const response = await fetch(url, {
      method: 'POST',
      headers: headers,
      body: body,
      agent: httpsAgent,
    });

Upvotes: 125

Elliot Blackburn
Elliot Blackburn

Reputation: 4174

process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";

Will ensure you ignore any rejected TLS certificates, or you can set this as an environment variable when running your node service. However this will likely not help, and is probably a bad idea. The SSL error is not because the certificate is invalid (such as a self signed certificate) but instead because of a weak Diffie-Hellman key in the SSL/TLS configuration.

If this a service you're hosting you should look at correcting and improving your TLS/SSL cyphers. See this answer for more information.

The important part is:

You should use 2048-bit Diffie-Hellman groups or larger. You should not be using 512-bit or 1024-bit Diffie-Hellman groups.

If this is a third party service, you should consider contacting them or using a different service as they are leaving themselves open to the Logjam attack which is also discussed in the answer linked above.

Upvotes: 114

Related Questions