
Cloud Storage Misconfigurations: Hunting Exposed S3 and GCS Buckets
A field guide to discovering, safely confirming, and accurately assessing impact on publicly exposed object storage across every major cloud provider.
Security research and platform engineering at HackerSavanna.
Exposed cloud storage is one of the oldest bug classes in the modern web, and it still shows up constantly, because the failure mode isn't a code bug at all. It's a configuration default that's easy to get wrong once and never revisit. This is a field guide to finding these misconfigurations methodically across S3, Google Cloud Storage, and Azure Blob Storage.
Why this bug class refuses to die
Object storage buckets default to private on every major provider today, which is genuine progress from a decade ago. But defaults get overridden constantly, for entirely reasonable-sounding reasons in the moment: a developer needs to quickly share a file with a client, a CI pipeline needs to publish build artifacts, a static site needs public read access to serve assets. Each of those is a legitimate use case. The problem is scope: "public read on this one folder of marketing assets" quietly becomes "public read on the whole bucket" far more often than anyone intends, and almost nobody audits bucket policies after the fact.
Discovery: finding the bucket in the first place
Bucket names aren't secret by design, they're just unglamorous strings, and most organizations use predictable naming conventions.
1# Common patterns worth trying against a target2company-assets3company-backups4company-uploads5company-static6company-dev7company-staging8company-prodCombine this with permutation tools built for exactly this purpose:
1# S3Scanner checks bucket existence and permission level in one pass2s3scanner scan --bucket-file company_bucket_names.txtPassive discovery is often more productive than guessing. Search engines index public bucket URLs that show up in JavaScript bundles, CDN configuration, or leaked CI logs:
1site:s3.amazonaws.com "company-name"2intitle:"index of" "s3.amazonaws.com" company-nameAnd check the target's own frontend JavaScript for hardcoded bucket references, which is often the fastest path of all:
1curl -s https://target.example.com/static/main.js | grep -oE "[a-z0-9.-]+\.s3[a-z0-9.-]*\.amazonaws\.com"Confirming exposure without touching data you shouldn't
Once you have a candidate bucket, confirm public access with a read-only, non-destructive request before doing anything else:
1aws s3 ls s3://target-bucket-name --no-sign-request--no-sign-request is the key flag. It makes the request as an anonymous, unauthenticated caller, which is exactly the perspective that matters for this finding. If the listing succeeds, you've confirmed public read access to the bucket contents without needing any credentials of your own.
For Google Cloud Storage, the equivalent check:
1gsutil ls gs://target-bucket-nameAnd for a quick, no-tooling-required check on any provider, a plain unauthenticated HTTP request to the bucket's listing endpoint often works:
1curl -s "https://target-bucket-name.s3.amazonaws.com/?list-type=2"A 200 response with an XML object listing is your confirmation. A 403 AccessDenied at least confirms the bucket exists, which is still worth documenting, since some programs consider bucket enumeration plus a misconfigured CORS policy or a related permissions gap in scope even when a straight listing is blocked.
What actually matters: assessing real impact
Not every exposed bucket is the same severity, and this is where reports frequently under- or over-state the finding. Before writing anything up, establish:
- Is it listable, readable, or writable? These are three different findings. Public write access, where anyone can upload or overwrite objects, is often the most severe, since it opens the door to serving attacker-controlled content from the company's own trusted domain, a supply chain risk far beyond simple data exposure.
- What's actually in it? A bucket serving public static assets for a marketing site is a non-issue by design. The same misconfiguration on a bucket containing user-uploaded documents, database backups, or
.envfiles pulled in by an overly broad CI artifact upload step is a critical data exposure. - Does it expose credentials that unlock further access? Backup buckets in particular frequently contain configuration files with database connection strings or API keys, turning a storage misconfiguration into a much deeper compromise if you follow the chain (responsibly, and within scope).
1# A sanity check for genuinely sensitive filenames, without downloading bulk data2aws s3 ls s3://target-bucket-name --no-sign-request --recursive | grep -iE "\.env|backup|\.sql|password|credentials|\.pem|\.key"Only pull down the minimum needed to confirm sensitivity for your report. Bulk-downloading an entire exposed bucket is rarely necessary to prove impact and can create real legal and ethical problems for you as a researcher.
Writing the report
A strong cloud storage exposure report includes:
- The exact bucket name and the provider
- The specific command or request used to confirm public access, so the triager can reproduce it in seconds
- A description of the type of data present, without needlessly reproducing large volumes of it (file names and a small representative sample are usually sufficient)
- Whether access is read-only or read-write
- A clear statement of realistic worst-case impact given what's actually stored there
Fixing it, and keeping it fixed
- Enable the provider's account-level public access block (
aws s3control put-public-access-blockfor AWS, equivalent settings exist for GCS and Azure) as a backstop against any individual bucket policy mistake. - Apply least-privilege bucket policies scoped to specific prefixes rather than whole-bucket wildcards when public access is genuinely needed for part of a bucket.
- Run continuous configuration auditing (AWS Config rules, Google Security Command Center, or third-party tools) rather than relying on a one-time review, since new buckets get created constantly and drift is the actual root cause here, not any single bad decision.
This bug class rewards persistence and good naming-convention instincts more than deep technical tooling, which is exactly why it remains one of the most consistently productive places to spend early recon time on any new target.
Related Posts

Reverse Engineering Android Apps for Hardcoded Secrets and Insecure Storage
A hands-on walkthrough of decompiling an APK, hunting for embedded credentials, and finding exported components that leak more than they should.

IDOR Hunting at Scale: From Manual Testing to Automated Discovery
A systematic methodology for finding broken object-level authorization across every method, endpoint, and hidden reference, not just the obvious ones.