Database Security Best Practices Cheat Sheet
Covers access control, encryption at rest and in transit, SQL injection prevention, and auditing practices for securing production databases.
3 PagesIntermediateMar 10, 2026
Access Control Fundamentals
Core principles for limiting who and what can reach your data.
- Principle of least privilege- Grant each user or service account only the minimum permissions needed for its job; avoid blanket SUPERUSER/root-equivalent access.
- Role-based access control (RBAC)- Define roles (readonly, app_writer, dba) with specific grants, then assign users to roles instead of granting permissions directly.
- Separate app and admin credentials- Application connection strings should use a low-privilege service account distinct from the credentials DBAs use for schema changes.
- Rotate credentials- Rotate database passwords and API keys on a schedule, and immediately after any suspected exposure such as a key committed to a repo.
- Multi-factor authentication- Enforce MFA for human access to the database console or admin panel (e.g. cloud provider IAM), not just the database password.
- Network isolation- Place databases in private subnets/VPCs with no public internet exposure; only allow inbound access from application servers via security groups or firewall rules.
Least-Privilege Roles (PostgreSQL)
Create a read-only role and lock down default public schema access.
sql
-- Create a read-only role for reportingCREATE ROLE readonly NOLOGIN;GRANT CONNECT ON DATABASE shop TO readonly;GRANT USAGE ON SCHEMA public TO readonly;GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly;ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO readonly;-- Create an application user and attach the roleCREATE USER app_reporting WITH PASSWORD 'use-a-secrets-manager' LOGIN;GRANT readonly TO app_reporting;-- Harden the public schema (older PostgreSQL versions grant CREATE on it by default)REVOKE ALL ON SCHEMA public FROM PUBLIC;
Encryption
Protecting data at rest, in transit, and in backups.
- Encryption at rest- Enable disk/volume-level encryption (AWS RDS storage encryption, LUKS) so data files are unreadable if the underlying disk is stolen.
- Encryption in transit- Require TLS/SSL for all client connections (sslmode=require or verify-full in Postgres) to prevent credentials and data from being sniffed on the network.
- Column-level encryption- Encrypt highly sensitive fields (SSNs, card numbers) at the application layer or with extensions like pgcrypto, so even DBAs with table access can't read plaintext.
- Transparent Data Encryption (TDE)- Available in SQL Server, Oracle, and some managed MySQL/Postgres offerings; encrypts data files and backups automatically with no application changes.
- Encrypted backups- Ensure backups and snapshots inherit encryption — an unencrypted backup of an encrypted database defeats the purpose.
- Secrets management- Never hardcode database credentials in code or config files; use a secrets manager (Vault, AWS Secrets Manager) with automatic rotation.
Preventing SQL Injection
Always use parameterized queries; never build SQL with string concatenation.
python
import psycopg2conn = psycopg2.connect(dbname="shop", user="app_reporting")cur = conn.cursor()# SAFE: parameterized query — the driver escapes the valuecur.execute("SELECT * FROM orders WHERE customer_id = %s", (customer_id,))# UNSAFE: never build SQL via string formatting/concatenation# cur.execute(f"SELECT * FROM orders WHERE customer_id = {customer_id}")# Named parameters work the same waycur.execute( "SELECT * FROM orders WHERE status = %(status)s AND amount > %(min)s", {"status": "paid", "min": 100},)
Auditing & Monitoring
Detecting misuse and verifying your safeguards actually work.
- Enable audit logging- Turn on native audit logs (pgaudit for Postgres, MySQL Enterprise Audit, SQL Server Audit) to record who ran what query and when.
- Log failed logins- Alert on repeated authentication failures, which can indicate brute-force or credential-stuffing attempts.
- Monitor privilege escalation- Alert whenever a role is granted SUPERUSER/DBA-equivalent privileges outside of a change-controlled process.
- Patch promptly- Apply database engine security patches quickly; unpatched CVEs in the DB engine itself are a common breach vector.
- Test backup integrity- Periodically restore backups to verify they're valid and untampered, not just that the backup job reported success.
Pro Tip
Enable row-level security (RLS) in PostgreSQL for multi-tenant applications — it enforces tenant isolation inside the database itself, so a bug in an application-layer WHERE clause can't leak another tenant's rows.
Was this cheat sheet helpful?
Explore Topics
#DatabaseSecurityBestPractices#DatabaseSecurityBestPracticesCheatSheet#Database#Intermediate#AccessControlFundamentals#Least#Privilege#Roles#Databases#Security#APIs#CheatSheet#SkillVeris
Advertisement
Sri Hayavadhana Info-Tech
Professional Web Designing Services
- Responsive Websites
- E-commerce Solutions
- SEO Friendly Design
- Fast & Secure
- Support & Maintenance