A database security checklist for SQL Server and PostgreSQL
A secure SQL Server or PostgreSQL database comes down to eight controls: no shared or password-free administrator logins, application roles with only the privileges they use, encrypted connections, encryption at rest, audit logs someone reads, current patches, backups that have been restored, and no exposure beyond the servers that need it. The findings that matter are usually in these defaults and in how applications connect, not in the engine itself.
What goes on a database security checklist?
| Control | SQL Server | PostgreSQL |
|---|---|---|
| Authentication | Prefer Windows authentication; keep sa disabled | No trust in pg_hba.conf; use scram-sha-256 |
| Least privilege | No application login in sysadmin | No superuser application role; revoke CREATE on public |
| Encryption in transit | Force Encryption, or Force Strict Encryption on 2022 and later | hostssl lines only for remote clients |
| Encryption at rest | Transparent Data Encryption | File-system or block-level disk encryption |
| Activity logging | Server-level audit logs | The pgAudit extension |
How should logins be set up?
Microsoft’s guidance on choosing an authentication mode is blunt: Windows authentication is much more secure than SQL Server logins, and the sa account is well known and often targeted, so do not enable it unless an application requires it. Name every login after a person or a service, never a shared one.
On PostgreSQL, the documentation for trust authentication says it lets anyone who can connect act as any user, superusers included. It still turns up on internal networks. Use SCRAM; MD5 password support is deprecated.
What privileges should the application have?
The most common finding is an application connecting with full administrative rights because it was easier during development. Give each application a role that can read and write its own tables and nothing else, and a separate role for schema migrations. Microsoft’s security best practices also suggest granting DBAs CONTROL SERVER rather than sysadmin, because sysadmin ignores DENY.
On PostgreSQL 15 and later, ordinary users can no longer create objects in the public schema by default. Databases upgraded from older versions keep the old permission until you revoke it.
How should data be encrypted, in transit and at rest?
Encrypt every connection, including those inside the data centre, and make clients verify the server certificate. The PostgreSQL client default, sslmode=prefer, does not; the libpq SSL documentation recommends verify-full in most security-sensitive environments. For SQL Server, connect with Encrypt=strict, where TDS 8.0 does not let the client set TrustServerCertificate to true, or keep TrustServerCertificate=false.
At rest, SQL Server’s TDE covers data files, logs, backups and tempdb; back up its certificate and private key immediately, or a restore elsewhere will fail. PostgreSQL’s encryption options point to file-system or block-level encryption instead.
Is encryption at rest enough? Only against a narrow threat. Encryption at rest protects stolen disks, files and backups; it does nothing against an attacker who logs in, because the database decrypts data for anyone with a valid session and the right privileges.
What about logging, patching and backups?
Turn on SQL Server’s audit logs or pgAudit for logins, permission changes and access to sensitive tables, and send them somewhere a database administrator cannot edit. Logs nobody reviews are storage, not a control.
Stay on a supported major version, and apply minor releases promptly; the PostgreSQL project recommends always running the current minor release. How do you know a backup works? Restore one, on a schedule, to a separate server, and time it. A backup that has never been restored is an assumption, and an encrypted backup whose key or certificate was not kept is not a backup at all.
Finally, the database should listen only to the application servers and administrative hosts that need it. The network side of that is in zero trust without buying a product; if the database is built with code, see the Terraform security checklist. The engine-by-engine review is our database security review.
How the work is bounded
The scope is agreed in writing before work starts, and the engagement is quoted in writing with it.
SecHB does not issue certifications, attestations or audit opinions: those come from accredited certification bodies, CPA firms and QSAs. The work here is what an organization does to be ready for them.
Nothing here is legal advice. Where a question turns on the law, the work is done alongside the client’s counsel, not instead of them.
Questions we are asked
Where should we start if we can only fix one thing?
Start with network exposure and authentication. A database that cannot be reached from the internet and that refuses unauthenticated or shared logins has already closed the doors most attacks walk through; everything else narrows what an intruder can do after that.
Does a managed database service handle this for us?
Partly. A managed service such as Azure SQL Database or Amazon RDS runs the servers underneath and makes encryption at rest a setting rather than a project, but roles, network rules, connection encryption settings and audit logs are still configured by you, and they are where the findings usually are.
Is encryption at rest enough?
Only against a narrow threat. Encryption at rest protects stolen disks, files and backups; it does nothing against an attacker who logs in, because the database decrypts data for anyone with a valid session and the right privileges.
How do we know our backups work?
Restore one, on a schedule, to a separate server, and time it. A backup that has never been restored is an assumption, and an encrypted backup whose key or certificate was not kept is not a backup at all.
Checking your own databases
Tell us which engines and versions you run and how applications connect. The reply says which items on this list we would check first. More of our writing is indexed at writing.