10 steps
Your database holds your most sensitive data. A single misconfiguration - an overly permissive user, an unencrypted connection, or a missing backup - can turn a minor breach into a catastrophic one. These steps systematically close the most common database exposure points.
Create a separate database user per application. Grant only the specific tables and operations (SELECT, INSERT, UPDATE) each user actually needs. Never use the database superuser account for application connections.
Require TLS for all client-to-database connections. Disable plaintext protocol fallback. Validate server certificates on the client side to prevent man-in-the-middle attacks on your data in transit.
Never concatenate user-supplied input directly into SQL strings. Use prepared statements and parameterized queries in every language and ORM. SQL injection remains one of the most prevalent and damaging vulnerabilities.
Log all DDL changes, privilege grants, failed login attempts, and access to sensitive tables. Route database audit logs to a centralized, tamper-resistant log store or SIEM for retention and alerting.
Automate encrypted, off-site backups on a regular schedule. Periodically run restore drills against a staging environment. An untested backup is not a backup - verify it works before you need it.
Prevent the database superuser (root, sa, postgres) from connecting over the network. Require local-socket access or explicit sudo escalation. Use named admin accounts with audit trails for DBA tasks.
Bind the database listener to internal interfaces only. Use firewall rules or cloud security groups to allow connections exclusively from known application servers and bastion hosts, not from the public internet.
Drop built-in demo users, sample schemas, and test databases (e.g., MySQL's test database, SQL Server's sample DBs). Change all vendor default passwords immediately after installation.
Subscribe to vendor security advisories for your database engine and apply updates promptly. Outdated database engines are frequent targets for remote code execution and privilege escalation exploits.
Place databases in private subnets with no public IP, allow inbound connections only from application tiers or a bastion via security groups, and require TLS with certificate verification. Disable default ports or listeners you do not use and alert on connections from unexpected sources.