A database connection without SSL transmits queries, parameters, and result sets as cleartext on the network. Any host on the path between the application server and the database — a shared VPC, a cloud provider's internal network, a compromised router — can read and modify query traffic. This is CWE-319 (cleartext transmission of sensitive information) and OWASP A02. The failure mode is especially dangerous because the exposed data includes authentication credentials passed as query parameters and result sets containing all user PII stored in the database. rejectUnauthorized: false is equally dangerous: it encrypts the channel but does not validate the server certificate, leaving the connection open to man-in-the-middle substitution.
High because cleartext database connections expose all query traffic — including credentials and PII — to any network observer between the application and database hosts.
Add ?sslmode=require to connection strings and ensure rejectUnauthorized is never set to false in production SSL config. For managed databases, verify SSL is enforced at the platform level.
// pg Pool — require SSL in production
export const pool = new Pool({
connectionString: process.env.DATABASE_URL,
ssl: process.env.NODE_ENV === 'production'
? { rejectUnauthorized: true }
: false
})
# .env.example — include sslmode in connection string template
DATABASE_URL=postgresql://USER:PASSWORD@HOST:PORT/DATABASE?sslmode=require
Search for dangerous patterns: grep -rn 'rejectUnauthorized.*false\|sslmode=disable\|NODE_TLS_REJECT_UNAUTHORIZED' . — any match in production config is a critical misconfiguration. For Neon serverless, the HTTP driver uses TLS by default with no additional config required.
ID: database-design-operations.security-access.connection-ssl
Severity: high
What to look for: Count every database connection configuration file and check the database connection configuration for SSL/TLS settings. In connection strings (.env.example pattern): look for ?sslmode=require or ?ssl=true. In pg Pool config: look for ssl: { rejectUnauthorized: true } or ssl: true. In Prisma DATABASE_URL: look for ?sslmode=require. In Drizzle config: check ssl option. For managed databases (Supabase, Neon, PlanetScale, AWS RDS): SSL is typically enforced by default from the platform side, but verify the connection string includes the appropriate SSL parameter. Dangerous patterns: sslmode=disable, ssl: false, rejectUnauthorized: false (disables certificate validation — exposes to MITM attacks). Check whether NODE_TLS_REJECT_UNAUTHORIZED=0 is set anywhere in scripts or environment config.
Pass criteria: Database connections use SSL/TLS — at least 1 SSL parameter present in connection configuration. Connection string includes sslmode=require or equivalent. SSL configuration does not disable certificate validation (rejectUnauthorized is not set to false in production). Managed database platforms confirm SSL is enforced.
Fail criteria: sslmode=disable in connection string. ssl: false in pool configuration. rejectUnauthorized: false in SSL config (disables cert validation, enables MITM). NODE_TLS_REJECT_UNAUTHORIZED=0 in production environment config.
Skip (N/A) when: SQLite (local file database — no network connection, SSL not applicable). Or all database connections are localhost-only in development with no remote database.
Detail on fail: Specify the misconfiguration. Example: "Connection string in .env.example uses ?sslmode=disable — database connections are unencrypted." or "pg Pool config has ssl: { rejectUnauthorized: false } — certificate validation disabled, connections vulnerable to MITM attacks.".
Remediation: Enable SSL with certificate validation:
// pg Pool — require SSL with certificate validation
import { Pool } from 'pg'
export const pool = new Pool({
connectionString: process.env.DATABASE_URL,
ssl: process.env.NODE_ENV === 'production'
? { rejectUnauthorized: true } // validate cert in production
: false, // allow no SSL in local development
})
// Or in connection string (simplest approach for managed DBs):
// DATABASE_URL=postgresql://user:pass@host/db?sslmode=require
# .env.example — connection string with SSL
DATABASE_URL=postgresql://USER:PASSWORD@HOST:PORT/DATABASE?sslmode=require
For Supabase/Neon/PlanetScale: SSL is enforced server-side. Add ?sslmode=require to your connection string as defensive configuration. For Neon with serverless driver: SSL is built into the HTTP transport — no additional config needed.