Skip to main content
In this lesson/article we run a database security audit against the Express login demo application. The audit inspects every database interaction, configuration, and operational control, then produces a prioritized remediation plan with concrete fixes and code snippets. Below you’ll find the audit flow summary, key checks and findings, evidence excerpts, and practical remediation guidance.
A dark-themed Visual Studio Code window with the project explorer on the left and a large editor/terminal pane showing a security checklist (items like query timeouts, audit & monitoring, PII in logs, and indexing of sensitive data). Files such as server.js, package.json, and schema.sql are visible in the sidebar.
Overview
  • Goal: Review every DB interaction in the repository and detect common weaknesses (SQL injection, credentials in source, missing TLS, weak pool/timeouts, PII leakage, multi-tenant isolation, etc.).
  • Output: A structured Markdown audit report written to audits/DATABASE_SECURITY_AUDIT_REPORT.md with findings, evidence, remediation steps, and a prioritized plan.
The audit tool indexes JavaScript files for DB usage patterns and configuration, extracts evidence snippets, and produces a machine-readable report. You can invoke the tool from the repository root to inspect specific files or produce the full DB audit.
Example of how the audit tool (Claude Code for Beginners) was run in the project:
What we check (summary checklist)
Key parts of the audit run
  • The tool scanned JS files to locate DB usage patterns (pool.query, client.query, raw SQL strings), pool usage, SSL/TLS config, and logging that might expose PII.
  • Grep-style checks look for driver usage, TLS keywords, console logging, and secret-like strings in .env.
Example grep/scan commands executed by the tool:
Sample search outputs (sanitized)
A screenshot of Visual Studio Code with a project explorer on the left and a dark-themed editor showing a numbered security checklist (items like sensitive data encryption, PII handling, query timeouts, and connection pool settings). The workspace appears to be an "express-login-demo" project with files like database.js and server.js visible.
Executive summary (consolidated)
  • Strengths: the app uses parameterized queries ($1 style) and bcrypt for password hashing; input validation is present (express-validator). These reduce injection and credential storage risk.
  • Major gaps to fix before production: missing TLS for DB connections, credentials present in development files, absent connection pool limits and statement timeouts, and lack of DB audit logging / RLS controls where applicable.
  • Risk score (pre-remediation): 6.5 / 10 (Medium-High). With prioritized fixes applied, target score: ~2.5 / 10 (Low Risk).

Critical findings (selected)

  • Strengths: the app uses parameterized queries ($1 style) and bcrypt for password hashing; input validation is present (express-validator). These reduce injection and credential storage risk.
  • Major gaps to fix before production: missing TLS for DB connections, credentials present in development files, absent connection pool limits and statement timeouts, and lack of DB audit logging / RLS controls where applicable.
  • Risk score (pre-remediation): 6.5 / 10 (Medium-High). With prioritized fixes applied, target score: ~2.5 / 10 (Low Risk).

CRITICAL: No TLS/SSL Encryption in Transit

  • Title: Database connections lack encryption
  • Severity: Critical
  • CWE: CWE-319 (Cleartext Transmission of Sensitive Information)
  • Evidence: config/database.js:3-9 — pool configuration does not include SSL settings; connections default to plaintext TCP.
Evidence excerpt:
Remediation (production-ready pg client example)
Do NOT disable SSL (ssl: false) in production. Ensure rejectUnauthorized: true and provide a CA cert (or platform-provided TLS) via environment or secrets manager. Failing to enable TLS exposes credentials and data in transit.

CRITICAL: Hard-coded placeholder credentials found

  • Evidence: .env contains JWT_SECRET=your_jwt_secret_key_here and DB_PASSWORD=your_db_password.
  • Remediation:
    • Remove real .env from the repo and purge it from Git history (use git filter-repo or git filter-branch).
    • Add .env to .gitignore, and commit a .env.example with placeholders.
    • Store production secrets in a secrets manager (AWS Secrets Manager, HashiCorp Vault, etc.) and inject into CI/CD or runtime environment.

HIGH: Test / placeholder bcrypt hash in SQL

  • Example:
  • Remediation: Remove or isolate test accounts from production data. Generate unique, properly salted bcrypt hashes for any seeded accounts.
Other notable issues
  • Missing connection pool limits and driver-level statement timeouts (risk: resource exhaustion).
  • No DB audit logging or DDL change monitoring identified.
  • No Row-Level Security (RLS) policies if multi-tenancy applies.
  • Some logging uses console.log/console.error and may expose PII — sanitize logs and avoid printing credentials.
Positive security practices observed
  1. Parameterized queries: SQL uses $1 placeholders (prevents SQL injection).
  2. Password hashing: bcrypt used for passwords.
  3. Input validation: express-validator used for primary inputs.
  4. Connection pooling: pg Pool is in use (needs production limits).
  5. Environment variables: credentials are sourced from environment variables (but .env needs secure handling).
Security Checklist Assessment (high-level) Priority remediation plan Immediate (Week 1)
  1. Enable TLS/SSL for database connections and verify server certificates.
  2. Remove .env from repository and add .env to .gitignore. Commit .env.example instead.
  3. Generate and store production secrets in a secrets manager.
  4. Add connection pool limits, idle timeouts, and statement timeouts.
Short-term (Month 1)
  1. Implement DB audit logging for authentication and privileged operations.
  2. Add client-side query timeouts and resource guards.
  3. Sanitize error logging to avoid PII leakage.
  4. Replace placeholder/test hashes and remove test accounts from prod seeds.
Medium-term (Month 2–3)
  1. Adopt a secrets management solution (AWS Secrets Manager, HashiCorp Vault).
  2. Add database monitoring, alerting, and anomaly detection.
  3. Implement data retention and deletion policies.
  4. Apply Row-Level Security (RLS) if multi-tenancy is required.
Risk score justification
  • +3: Missing TLS and credential management (critical exposure)
  • -2: Strong use of parameterized queries and input validation
  • +1: Missing enterprise controls (audit, timeouts)
  • +1: Development defaults not hardened for production
Target score after prioritized fixes: approximately 2.5 / 10 (Low Risk)
A screenshot of Visual Studio Code showing a project explorer on the left and a document open in the main pane. The open file contains a numbered security checklist with items like secret management & rotation, schema & integrity controls, field‑level minimization, pagination limits, and backup/restore security.
Additional practical remediation snippets
  • Enforce per-statement timeouts at the client level (pg example):
  • Sanitize logs to avoid PII leaks:
  • Use environment-driven pool defaults and sensible production values:
  • Example .env.example (commit this file; never commit real secrets):
A screenshot of Visual Studio Code with a dark theme, showing a project explorer on the left and an open editor/terminal pane containing a security/audit checklist about sensitive data, analytics exports, and critical flags. The file tree shows project files like package.json, server.js, and schema.sql.
Conclusion
  • The Express login demo demonstrates solid foundations (parameterized queries, bcrypt, input validation), which reduce injection and credential storage risk.
  • Critical production hardening is required before public deployment: enable TLS, remove sensitive files from source, configure pool/timeouts, introduce audit logging, and adopt a secrets manager.
  • Implement the prioritized remediation plan above — these concrete fixes will materially reduce risk quickly.
Recommended follow-up
  • Expand scope to API and infrastructure security: ingress controls, network ACLs, and cloud resource configuration.
  • Validate database server-side controls (encryption at rest, user roles, audit logging, and backups).
References and further reading

Watch Video