Database security is not a one-time configuration task but a continuous discipline that separates resilient systems from breach statistics. Every database engine—whether PostgreSQL, MySQL, SQL Server, Oracle, or MongoDB—shares a common attack surface: misconfigured access controls, weak authentication, unencrypted data, and unpatched vulnerabilities. This checklist distills vendor-neutral hardening practices into actionable steps that any DBA can implement today, regardless of the engine under management.
Why a Baseline Security Checklist Matters
A baseline checklist eliminates the guesswork from database hardening. Without one, teams rely on tribal knowledge, inconsistent manual reviews, or default configurations that often leave critical gaps. Attackers exploit these gaps: default ports, shared credentials, and overly permissive roles are the low-hanging fruit of database breaches. A standardized baseline ensures every deployment—development, staging, and production—meets a minimum security bar before it goes live. It also simplifies compliance audits by providing a repeatable, documented process.
Principle of Least Privilege: Users, Roles, and Permissions
The principle of least privilege (PoLP) dictates that every database user should have only the permissions necessary to perform their function—nothing more. Start by auditing all existing users and roles. Remove or disable unused accounts, especially default administrative accounts like sa (SQL Server), root (MySQL), or postgres (PostgreSQL) for routine operations. Create application-specific roles with granular permissions, avoiding blanket grants like SELECT * or ALL PRIVILEGES.
For example, in PostgreSQL, grant only the required schema-level access:
-- Create a read-only role for reporting
CREATE ROLE reporting_user WITH LOGIN PASSWORD 'strong_password';
GRANT CONNECT ON DATABASE sales_db TO reporting_user;
GRANT USAGE ON SCHEMA public TO reporting_user;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO reporting_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO reporting_user;
In SQL Server, use contained database users and avoid server-level logins where possible. Regularly review permissions with queries like sys.database_permissions or information_schema.role_table_grants.
Rule of thumb: If a user can create, drop, or alter objects without explicit business justification, your least privilege implementation is broken. Revoke and rebuild from the application layer up.
Network Security: Firewalls, TLS, and Isolation
Database ports should never be exposed to the public internet. Use host-based firewalls (e.g., iptables, Windows Firewall) or cloud security groups to restrict access to only trusted IP ranges—typically application servers and admin jump boxes. Disable any network protocols not in use, such as NetBIOS or named pipes in SQL Server.
Enforce TLS 1.2 or higher for all client-server connections. Require client certificates for mutual TLS (mTLS) in high-security environments. For example, in MySQL, force TLS by setting:
-- In my.cnf or my.ini
[mysqld]
require_secure_transport = ON
ssl-ca = /etc/mysql/ca-cert.pem
ssl-cert = /etc/mysql/server-cert.pem
ssl-key = /etc/mysql/server-key.pem
Isolate database servers in a dedicated VLAN or subnet with strict egress rules. Never allow a database server to initiate outbound connections to the internet unless explicitly required for replication or monitoring.
Encryption at Rest and in Transit
Encryption at rest protects data if physical media is stolen or improperly decommissioned. Use native transparent data encryption (TDE) where available—SQL Server TDE, PostgreSQL pgcrypto or filesystem-level encryption, MySQL InnoDB tablespace encryption. For MongoDB, enable encryption at rest via WiredTiger storage engine configuration. Always manage encryption keys separately from the database, using a hardware security module (HSM) or key management service (KMS).
Encryption in transit is non-negotiable. Disable older protocols like SSL 3.0 and TLS 1.0/1.1. Verify that all application connection strings specify sslmode=require (PostgreSQL), encrypt=true (SQL Server JDBC), or ssl-mode=REQUIRED (MySQL). Regularly test with tools like openssl s_client or nmap to confirm no unencrypted listeners remain.
Authentication Hardening and Credential Management
Default authentication methods are often weak. Replace password-based authentication with integrated Windows/Linux authentication or LDAP/Active Directory where possible. For PostgreSQL, use pg_hba.conf to enforce cert or gss methods. For MySQL, map users to system accounts via auth_socket or pam.
When passwords are unavoidable, enforce strong password policies: minimum 12 characters, complexity requirements, and regular rotation. Store application credentials in a secrets manager (e.g., HashiCorp Vault, AWS Secrets Manager) and never hardcode them in configuration files or source code. Implement account lockout policies after a small number of failed login attempts (e.g., 5 attempts with a 15-minute lockout).
Auditing, Monitoring, and Anomaly Detection
Enable database auditing to log all schema changes, privilege grants, failed logins, and data access to sensitive tables. Each engine provides native auditing: PostgreSQL pgaudit extension, SQL Server Audit, MySQL Audit Plugin, Oracle Unified Auditing. Centralize these logs in a SIEM or log management platform (e.g., Elasticsearch, Splunk) for correlation and alerting.
Monitor for anomalies: unusual query patterns (e.g., full table scans on sensitive columns), login spikes from unfamiliar IPs, or bulk data exports. Set alerts for common indicators of compromise, such as multiple failed authentication attempts or unexpected privilege escalations. Review audit logs weekly, not just after an incident.
Patch Management and Configuration Baselines
Unpatched databases are the leading cause of known-vulnerability exploits. Subscribe to your engine's security advisory list (e.g., PostgreSQL pgsql-announce, Oracle Critical Patch Update) and apply critical patches within 30 days. Use a staging environment to test patches before production deployment.
Establish a configuration baseline using tools like pg_config, sp_configure, or database-specific hardening guides (CIS Benchmarks). Automate configuration drift detection with scripts that compare current settings against the baseline. For example, in PostgreSQL, check for insecure settings:
SELECT name, setting, boot_val
FROM pg_settings
WHERE name IN ('password_encryption', 'ssl', 'log_statement', 'log_connections')
AND setting != boot_val;
Document every configuration change and its rationale. Revert any setting that deviates from the baseline without approval.
The short version
Database security hardening boils down to seven actions: enforce least privilege for all users, lock down network access with firewalls and TLS, encrypt data at rest and in transit, harden authentication and manage credentials centrally, enable comprehensive auditing and monitoring, patch vulnerabilities promptly, and maintain a documented configuration baseline. Implement these steps consistently across every database engine, and you eliminate the most common attack vectors before they become incidents.
About this article
Drafted by Connect·IT's AI authoring agents and reviewed by our senior DBAs before publishing. Need this applied to your own systems? Talk to our team →