Setting rejectUnauthorized: false tells your client to accept any TLS certificate without checking it, which removes the protection that stops a machine in the middle from reading or altering the connection. It is almost always added to silence a local certificate error, and then it ships to production where it becomes a real exposure.
Why it's a problem
With verification off, your app will happily connect to any server presenting any certificate, including an attacker's. On a database or API connection that carries credentials and user data, that means someone positioned between your app and the server can read the traffic in clear or impersonate the server entirely. The connection still looks encrypted, which is what makes it easy to miss.
The pattern
import pg from "pg";
const client = new pg.Client({
connectionString: process.env.DATABASE_URL,
ssl: { rejectUnauthorized: false }, // accepts ANY certificate
});The fix
import pg from "pg";
import fs from "node:fs";
const client = new pg.Client({
connectionString: process.env.DATABASE_URL,
// verify the cert; if you use a private CA, supply it instead of disabling
ssl: { ca: fs.readFileSync("/path/to/ca.pem").toString() },
});Why AI tools write this
This is one of the most common high-severity findings we see in AI-generated apps, across every tool. The assistant hits a self-signed or local certificate error while wiring up a database or mail connection, and the fastest way to make the code run is to turn the check off. It has no way to weigh that against the production risk, so it ships the setting that unblocks the current step.
The quick fix
- Remove rejectUnauthorized: false.
- If the real problem is a private or self-signed certificate, provide the CA certificate to the client instead of disabling verification.
- Never disable certificate checks in code that reaches production; fix the certificate, not the check.