Database connections use SSL/TLS
Why it matters
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.
Severity rationale
High because cleartext database connections expose all query traffic — including credentials and PII — to any network observer between the application and database hosts.
Remediation
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.
Detection
-
ID:
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.examplepattern): look for?sslmode=requireor?ssl=true. InpgPool config: look forssl: { rejectUnauthorized: true }orssl: true. In PrismaDATABASE_URL: look for?sslmode=require. In Drizzle config: checkssloption. 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 whetherNODE_TLS_REJECT_UNAUTHORIZED=0is 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=requireor equivalent. SSL configuration does not disable certificate validation (rejectUnauthorizedis not set tofalsein production). Managed database platforms confirm SSL is enforced. -
Fail criteria:
sslmode=disablein connection string.ssl: falsein pool configuration.rejectUnauthorized: falsein SSL config (disables cert validation, enables MITM).NODE_TLS_REJECT_UNAUTHORIZED=0in 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=requireFor Supabase/Neon/PlanetScale: SSL is enforced server-side. Add
?sslmode=requireto your connection string as defensive configuration. For Neon with serverless driver: SSL is built into the HTTP transport — no additional config needed.
External references
- cwe · CWE-319 — Cleartext Transmission of Sensitive Information
- owasp:2021 · A02 — Cryptographic Failures
Taxons
History
- 2026-04-18·v1.0.0·Initial import from database-design-operations·automated