
The Cloud Settings That Leak Data
The cloud incidents that make the news rarely involve a clever attack. They involve a storage bucket someone made public for a quick test, an access key committed to a repository, or a permission that was widened to unblock a deploy on a Friday and never narrowed again. The defence is unglamorous and mostly consists of checking things. This post lists the settings worth checking and how to verify each one on your own account.
Storage that is public without anyone deciding it should be
Object storage is the most common source of accidental exposure, because making a file readable by everyone sits one setting away from making it readable by your application. Backups, database dumps, user uploads and log archives all end up there.
Check three layers, because any one of them can open the door on its own:
- Account level. The major providers offer a switch that blocks public access across the whole account regardless of what individual buckets say. Turn it on unless you deliberately host a public site from a bucket.
- Bucket level. List your buckets and look at their access settings, not their names. A bucket called
internal-backupstells you nothing about who can read it. - Object level and signed URLs. An individual file can be public inside a private bucket. Signed URLs are a good pattern, but check the expiry: a link valid for ten years is a public file with extra steps.
The verification is simple. Take the URL of a private object and open it in a browser where you are not logged in, or fetch it with curl from a machine with no credentials. If you get the file, so does everyone else.
Permissions that grew
Permissions tend to widen over time and never narrow, because widening fixes an outage and narrowing risks one. The result is service accounts that can do far more than their job requires, so a single leaked credential compromises the whole account rather than one function.
Three habits keep this under control:
- No wildcards in production policies. A policy granting every action on every resource is a policy nobody has read. Name the actions and the resources, even though it is more work.
- Short-lived credentials over long-lived keys. Workload identity, instance roles and OIDC federation let a running service obtain temporary credentials without storing a key anywhere. A credential that expires in an hour is a much smaller prize than one that never expires.
- Separate accounts or projects per environment. Staging should not be able to reach production data at all. This is the control that survives a mistake in every other control.
Most providers report when each credential was last used and which permissions were actually exercised. That report is the fastest way to find keys you can delete and permissions you can drop without breaking anything.
Secrets in places that keep copies
A secret does not have to be published to leak. It only has to sit somewhere that keeps history or is readable by more people than you think.
- Version control. Removing a key in a later commit does not remove it from the history. If a key was ever committed, treat it as compromised and rotate it, then clean the history.
- Build logs and CI output. An environment variable echoed by a debug line ends up in a log that is often readable by everyone in the organisation, and sometimes by the public on open-source projects.
- Client bundles. Anything shipped to a browser is public. A key with a publishable prefix is designed for that; a service key is not, and the difference is worth checking rather than assuming.
- Error reporting and analytics. Payloads sent to a third party for debugging can carry tokens and personal data. Scrub them at the source.
Scanning helps here: several open-source tools search a repository and its history for credential patterns, and most hosting platforms scan pushes for known key formats. Run one over your repositories once, then wire it into the pipeline so it keeps running.
Databases and the network around them
A managed database with a public endpoint is reachable by anyone who guesses the hostname, and hostnames are not secret. Put it on a private network and reach it through a bastion or a connector, or at minimum restrict inbound addresses to the ranges that legitimately need it.
If your application lets a browser talk to the database directly, as the backend-as-a-service platforms do, then the access rules in the database are your entire authorisation layer. Every table needs a policy, and a policy named after a role is not the same as a policy that checks one. Test it the way an attacker would: take an anonymous key, try to read a table you believe is private, and confirm you get nothing back.
Logging you can actually use afterwards
The question after an incident is always the same: what did they reach, and when? You can only answer it if the logs were already on. Audit logging of control-plane actions, access logs on storage, and logs of administrative database actions all need to be enabled before you need them, and stored somewhere the same credentials cannot delete.
Retention matters as much as collection. Intrusions are often discovered weeks later, and a seven-day window is frequently shorter than the gap between the breach and the discovery.
Accounts, especially the forgotten ones
Multi-factor authentication on every human account, including the root or owner account nobody uses day to day, is the highest-value setting in this whole list. After that, look at leavers: an offboarding process that removes the email account but leaves the cloud account intact is common, and the abandoned account keeps its permissions.
Service accounts deserve the same walk-through. The integration you trialled last year probably still holds a token with the access you granted it.
A check you can run this week
Set aside an afternoon and work through it in this order: turn on account-level public access blocking, list every storage bucket and confirm the intended visibility of each, review credentials by last-used date and delete the dormant ones, run a secret scanner over your repositories and their history, confirm MFA on every human account, and check that audit logs are on with a retention period measured in months.
Write down what you found and what you changed. Most of these settings drift back over time, so the value comes from repeating the pass, not from doing it perfectly once.
Comments
No comments yet. Be the first to share your thoughts.


