no-insecure-ssl
Prevents disabling SSL certificate validation in PostgreSQL connections.
CWE: CWE-693
⚠️ This rule errors by default in the recommended config.
Quick Summary
| Aspect | Details |
|---|---|
| CWE Reference | CWE-295 (Improper Certificate Validation) |
| Severity | High (CVSS: 7.5) |
| Category | Security |
Rule Details
Setting rejectUnauthorized: false disables SSL certificate verification, making connections vulnerable to man-in-the-middle attacks.
❌ Incorrect
const client = new Client({
ssl: {
rejectUnauthorized: false, // Dangerous!
},
});
const pool = new Pool({
ssl: {
rejectUnauthorized: false,
},
});✅ Correct
// Default (secure)
const client = new Client({ ssl: true });
// With CA certificate
const client = new Client({
ssl: {
ca: fs.readFileSync('/path/to/server-ca.pem').toString(),
},
});
// Explicit secure setting
const client = new Client({
ssl: {
rejectUnauthorized: true,
},
});Error Message Format
🔒 CWE-295 | Insecure SSL: rejectUnauthorized: false disables certificate validation | HIGH
Fix: Remove rejectUnauthorized: false or set to true, and provide CA certificateWhen Not To Use It
- In development environments with self-signed certificates (use environment variables instead)
- Never disable in production
Known False Negatives
The following patterns are not detected due to static analysis limitations:
Also checked (since 2026-10)
- Every branch of a conditional
sslvalue —ssl: isProd ? { rejectUnauthorized: false } : false, the widely copied Heroku snippet, disables verification in exactly the environment that matters. - postgres.js
postgres(url, { ssl })and pg-promisepgp({ ssl }). - A config returned from a function in the same file, and a config object
declared with pg's
PoolConfig/ClientConfigtype (orsatisfiesit).
Configuration Object from a package or path alias
Why: A config imported from a RELATIVE module or JSON file is read
(import dbConfig from './database.json' is reported when it sets
rejectUnauthorized: false). One from an npm package or a path alias is not.
// ❌ NOT DETECTED - config from a path alias
import dbConfig from '@/config/database';
const client = new Client(dbConfig);Spread Operator
Why: Spread objects hide their properties at lint time.
// ❌ NOT DETECTED - rejectUnauthorized in spread
const baseConfig = getDbConfig();
const client = new Client({ ...baseConfig }); // May include insecure SSLMitigation: Explicitly set SSL options. Validate config at runtime.
Related Rules
- no-hardcoded-credentials - Prevents hardcoded passwords
Use this rule
npm install -D oxlint-plugin-postgresql-security{ "jsPlugins": ["oxlint-plugin-postgresql-security"], "rules": { "postgresql-security/no-insecure-ssl": "error" }}import { defineConfig } from 'vite-plus';export default defineConfig({ lint: { jsPlugins: ['oxlint-plugin-postgresql-security'], rules: { 'postgresql-security/no-insecure-ssl': 'error', }, },});oxlint-plugin-postgresql-security re-exports eslint-plugin-postgresql-security/oxlint: the same rules under the same IDs, and no ESLint install. Why oxlint.
Did this rule catch something? Star the repo to get new CWE coverage as we ship it — or follow the AI-code-security benchmarks behind these rules.