v0.14 is out: a mobile auth pack for Swift/iOS and Android, catching insecure token storage, cleartext traffic, and OAuth in embedded WebViews. Read more →
HIGH AI PREVALENCE: HIGH auth.tls.reject-unauthorized

TLS certificate validation is disabled for this connection.

Why AI tools produce this: AI coding tools generate this anti-pattern by default, it appears in a large share of AI-written auth code.

Why this matters

Setting rejectUnauthorized: false or NODE_TLS_REJECT_UNAUTHORIZED=0 makes the connection accept ANY certificate, including self-signed or attacker-supplied ones. This removes the protection TLS provides against man-in-the-middle attacks: anyone able to intercept the network path can present a forged certificate, then read and modify the traffic (credentials, tokens, data).

Keep certificate validation enabled. If the server uses a private or self-signed CA, supply that CA explicitly instead of turning validation off, e.g. new https.Agent({ ca: fs.readFileSync('ca.pem') }). See CWE-295 and the Node.js TLS docs.

VULNERABLE
vulnerable.ts
import axios from 'axios';
import https from 'node:https';
import tls from 'node:tls';

declare const url: string;

// A custom HTTPS agent that accepts any certificate — classic MITM hole.
// ruleid: auth.tls.reject-unauthorized
const insecureAgent = new https.Agent({ rejectUnauthorized: false });

// axios call wiring up the same insecure agent inline.
// ruleid: auth.tls.reject-unauthorized
const res = axios.get(url, {
  httpsAgent: new https.Agent({ rejectUnauthorized: false }),
});

// Raw https.request options with validation disabled.
// ruleid: auth.tls.reject-unauthorized
const req = https.request({
  hostname: 'api.example.com',
  port: 443,
  rejectUnauthorized: false,
});

// tls.connect with validation disabled.
// ruleid: auth.tls.reject-unauthorized
const socket = tls.connect({ host: 'api.example.com', port: 443, rejectUnauthorized: false });

// The global escape hatch that disables validation process-wide.
// ruleid: auth.tls.reject-unauthorized
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';

export { insecureAgent, res, req, socket };
SAFE
safe.ts
import axios from 'axios';
import fs from 'node:fs';
import https from 'node:https';

declare const url: string;

// ok: auth.tls.reject-unauthorized -- validation explicitly kept on
const strictAgent = new https.Agent({ rejectUnauthorized: true });

// ok: auth.tls.reject-unauthorized -- plain request, default validation applies
const res = https.get(url);

// ok: auth.tls.reject-unauthorized -- pins a private CA instead of disabling checks
const pinnedAgent = new https.Agent({ ca: fs.readFileSync('ca.pem') });

// ok: auth.tls.reject-unauthorized -- axios call with no insecure options
const data = axios.get(url, { timeout: 5000 });

export { strictAgent, res, pinnedAgent, data };

Suppressing this rule

If a finding is a genuine false positive, scope the suppression to the exact line and leave a reason, never disable the rule project-wide. Disable directives are line-scoped by design.

// oauthlint-disable-next-line auth.tls.reject-unauthorized -- <reason>

References

https://nodejs.org/api/tls.html#tlsconnectoptions-callback ↗https://cwe.mitre.org/data/definitions/295.html ↗