OWASP's Database Security Cheat Sheet asks for five things: isolate the database network, encrypt connections, give each app its own authenticated account, keep credentials out of source code, and grant only the permissions needed. This post turns that guidance into a checklist you can run against your own setup.
Isolation
The cheat sheet says the backend database should be isolated from other servers and connect with as few hosts as possible. It suggests disabling TCP access where possible so that access is over a local socket or named pipe, binding the database to localhost, restricting the port to specific hosts with firewall rules, and placing the server on a dedicated internal network segment. It also says to protect web based management tools such as pgAdmin with authentication, HTTPS and network restrictions.
One more rule applies to apps that run on untrusted systems, such as thick clients. They should connect through an API that can enforce access control, and direct connections from a thick client to the database should never be made.
Transport protection
Most database defaults start with unencrypted network connections, the cheat sheet notes. Its steps are to allow only encrypted connections, install a trusted certificate, connect with TLS 1.2 or later with modern ciphers, and have the client verify the certificate. See PostgreSQL sslmode and MySQL secure transport.
Authentication and accounts
The database should always require authentication, including for local connections. Accounts should have strong, unique passwords, be used by a single application or service, and hold the minimum permissions required. Review accounts and permissions regularly, remove accounts when an application is retired, and change passwords when staff leave or compromise is suspected.
Storing credentials
Credentials should never be stored in application source code. The sheet says to keep them in a configuration file that is outside the web root, readable only by the required users, and not checked into source repositories. See env example files, what to commit.
Permissions
The sheet lists what to do in all environments:
| Do | Do not |
|---|---|
| Use separate accounts for development, UAT and production | Use the built in root, sa or SYS accounts |
| Let the account connect only from allowed hosts | Grant administrative rights over the instance |
| Limit access to the specific databases needed | Make the account the owner of the database |
| Grant only the required permissions on those databases | Rely on database links without limiting them |
It notes most applications need SELECT, UPDATE and DELETE and that the account should not own the database, since that can lead to privilege escalation. Security critical applications go further with table, column and row level permissions, or by blocking access to base tables and requiring access through restricted views.
Turning it into a review
- For each database, write down which hosts can reach it and how.
- Confirm TLS is mandatory and the client verifies the certificate.
- List the accounts and which service uses each. Remove shared ones.
- Check where each credential is stored and who can read it.
- Check each account's grants against what the service really does.
- Confirm lower environments have separate databases and accounts. See dev and prod parity, a security view.
Pair this with separate migration and runtime roles to handle the ownership point, and the database hardening checklist for engine specific steps.
Safeguard scans dependencies, including database drivers and clients, and can find exposed secrets in repositories. A free scan is at gold.safeguard.sh/scan.
Quick check
Should the app account own the database?
The cheat sheet says no, because ownership can lead to privilege escalation vulnerabilities.
Should dev and production share a database account?
No. The sheet says development, UAT and production should use separate databases and accounts.
Where should credentials live?
Outside source code, in a protected configuration location not checked into repositories.
Sources
Last reviewed: 19 October 2026.