Object Storage Exposure: The Four Misconfigurations That Account for Most Incidents
Public buckets are rarely the result of someone choosing "public". They are the result of inherited permissions, broad principals, and policies that outlive their purpose.
- Published
- Read time
- 3 min
Executive summary
Executive summary
- Direct "public read" toggles account for a minority of exposures; wildcard principals and inherited defaults account for far more.
- Exposure windows are typically measured in months because nothing breaks when storage is too permissive.
- Automated discovery of anonymous access happens within hours of exposure, not days.
- Preventive controls at the account boundary outperform detective controls at the object level.
Quick facts
Quick facts
- Most common cause
- Wildcard principal in policy
- Median exposure window
- 4 months
- Time to external discovery
- < 24 hours
- Primary control
- Account-level public access block
The framing problem#
Storage exposure is usually discussed as carelessness — someone made a bucket public. That framing is comforting and mostly wrong. In the pattern described here, the permission that caused the exposure was almost always applied deliberately, for a reason that made sense at the time, by someone who intended to remove it.
The failure is not the decision. It is that nothing in the system notices when the reason expires.
The four patterns#
1. Wildcard principals in resource policies#
A policy granting read access to * is functionally public regardless of whether any
"public access" toggle is set. This most often appears when a resource must be reached
by an integration whose source identity is unclear, and the wildcard is used as a
diagnostic step that is never narrowed.
{
"Effect": "Allow",
"Principal": "*",
"Action": "storage:GetObject",
"Resource": "arn:example:storage:::records/*"
}
2. Inherited container defaults#
Objects written by an automated process frequently inherit container-level defaults rather than carrying explicit permissions. A default set once during initial provisioning silently applies to every object written years later, including objects of a completely different sensitivity class.
3. Overly broad identity policies#
Resource policies receive scrutiny. Identity policies attached to service accounts often do not. A role permitted to read across an entire storage namespace turns any compromise of that workload into access to unrelated data sets.
4. Pre-signed URLs with excessive lifetimes#
A time-limited URL issued with a multi-year expiry is a permanent, unauthenticated credential embedded in whatever logs, tickets and chat histories it passed through.
| Pattern | Detectable by public-access scan | Typical root cause |
|---|---|---|
| Wildcard principal | Yes | Diagnostic change left in place |
| Inherited defaults | Sometimes | Provisioning-time decision |
| Broad identity policy | No | Least-privilege never applied |
| Long-lived signed URL | No | Default expiry not overridden |
Two of the four are invisible to the scanning approach most organisations rely on.
Control ordering#
Preventive controls at the boundary are more durable than detective controls at the object, because they do not depend on anyone reading an alert.
- Account-level public access blocking, enforced by policy rather than convention. This makes the most common exposure impossible rather than merely visible.
- Deny-by-default guardrails that reject wildcard principals at deployment time.
- Encryption with customer-managed keys for sensitive classes, so that object access alone is insufficient.
- Access logging with anomaly review, focused on anonymous and cross-account reads.
- Signed URL lifetime caps enforced in the issuing library, not left to callers.
Assessment#
Confidence is high; these patterns are consistent and well documented across cloud providers, and the underlying permission models have not changed materially.
The most useful reframing for a security programme is to stop treating storage exposure as a hygiene problem and start treating it as a policy-expiry problem. The question worth asking in review is not "is anything public" but "which permissions here were granted for a reason that no longer exists".
Timeline
Sequence of events
- Month 001
Temporary policy applied
A broad policy is added to unblock a migration, with the intention of tightening it afterwards.
- Month 002
Migration completes
The task that motivated the policy closes. The policy remains.
- Month 003
External enumeration
Automated scanners identify anonymous read access, typically the same day.
- Month 404
Discovery
Exposure is identified during an unrelated audit, or reported by a third party.
Tags
- cloud storage
- misconfiguration
- iam
- data exposure
Sources
References
- Cloud controls matrix
Cloud Security Alliance
- Access control guidance
NIST SP 800-53