From one web foothold to the entire data tier: why a database superuser is your real blast radius
When we test an application, the interesting question is rarely "can we get in?" It's "once we're in, how far does it go?" On a recent internal assessment of a platform processing regulated data for multiple tenant banks, the answer was: much too far. A single foothold in one application container led, step by step, to read/write access across every tenant's database and the ability to forge any user's session. Nothing there was exotic. The problem was blast radius — and blast radius is a design choice.
The starting point: assume the container is compromised
We began where a real incident often does: code execution inside one production application container. Not domain admin, not the database — just the app, running as itself. The job from there is to measure what that single process can actually reach.
Step 1 — Secrets sitting in plaintext at runtime
The platform decrypted its secrets at container start and left them readable in the environment and config of the running process. So the first thing our foothold could do was simply read them: database credentials, signing keys, deploy keys, partner transfer keys. Encryption at rest is worth little if the decrypted values sit in plaintext next to the thing that gets compromised.
Lesson: inject secrets at the last possible moment, keep them out of the process's broad environment, and prefer short-lived, brokered credentials over static ones baked into config.
Step 2 — The database account was a cluster superuser
This is the hinge of the whole chain. The credential the application used to talk to its database wasn't scoped to the application's data — it was a cluster superuser, reachable directly from the app container. With it, our foothold had read/write across dozens of tenant databases, including a central credit-risk dataset of millions of rows and the shared SSO user store, plus command execution on the database host itself.
One compromised web process should never be able to read another tenant's data, let alone every tenant's. The application account should have exactly the privileges the application needs on exactly the data it owns — nothing more.
Lesson: least privilege at the database tier is the single highest-leverage control here. Demote application accounts from superuser, scope them per-schema/per-tenant, and network-restrict the database so only its application hosts can reach it.
Step 3 — The session-signing key meant game over
Among the readable secrets was the production session-signing key. We proved its impact offline — reproducing a real session signature — which meant an attacker holding it could forge a valid session for any user, role or tenant, without ever authenticating. At that point, access control in the application above it is decorative.
Lesson: signing keys belong in a secrets manager or HSM, out of any application-readable path, and must be rotatable. If a key like this is ever exposed, rotation is the only remedy — so make it a one-step operation, not a project.
Step 4 — The keys kept going
The same readable config also held a GitOps deploy key (a route back into the software supply chain) and passphrase-protected partner file-transfer keys — whose passphrases were, of course, in the same file. A good chain rarely stops at the first prize; it keeps pulling threads until something structural stops it. Here, nothing did until we chose to stop.
How to cap the blast radius
- Least privilege at the data tier. No application account should be a database superuser. Scope to the data it owns.
- Network-segment the database. Reachable only from its application hosts, never broadly.
- Secrets late and short-lived. Inject at runtime, keep out of the broad process environment, prefer brokered/temporary credentials.
- Signing keys in an HSM/secrets manager, with one-step rotation.
- Assume the container falls. Design so that one compromised process is a contained incident, not a company-wide one.
The difference between a bad day and a breach notification is almost never whether an attacker got in. It's how much a single foothold could reach once they did.
How far would one foothold reach in your environment?
An internal or cloud penetration test measures exactly that — the real blast radius from a realistic starting point. See our penetration testing and cloud testing.
Request a proposal