SecureBlockLog inStart a pentest
Vulnerability Repository
CriticalMisconfiguration

Cloud Storage Misconfiguration

Publicly accessible cloud storage buckets expose sensitive files, backups, and internal data to unauthenticated access, frequently resulting in large-scale data breaches.

CVSS 9.8CWE CWE-284OWASP A05:2021 — Security Misconfiguration

Description

Cloud storage misconfiguration (CWE-284 — Improper Access Control) is one of the most frequently exploited vulnerability classes in cloud environments. It occurs when object storage services — AWS S3, Google Cloud Storage (GCS), Azure Blob Storage, or equivalent — are configured to allow public read (or write) access without authentication. The resulting exposed buckets contain a disproportionate share of the most sensitive data in modern organizations: database backups, user data exports, log archives, application assets including private keys and configuration files, medical records, financial documents, and proprietary intellectual property.

This is classified under A05:2021 — Security Misconfiguration and rated critical (CVSS 9.8) because the data exposed is often the full scope of the organization's sensitive information, accessible with a single unauthenticated HTTP GET request requiring no technical skill whatsoever. Attackers do not need to exploit a vulnerability — they simply request the object. Automated scanning tools discover publicly accessible buckets continuously across the internet, meaning exposed data is often accessed within hours of the misconfiguration being introduced.

Cloud storage misconfiguration has been responsible for some of the largest and most publicized data breaches in recent history, affecting healthcare providers, financial institutions, government agencies, and technology companies. The consistency and scale of this issue reflects a systemic challenge: cloud storage services default behavior and IAM policy complexity create frequent misconfigurations even in security-conscious organizations.

How It Works

A developer creates an S3 bucket for user profile pictures and mistakenly configures it as public to simplify image delivery, not realizing they also stored a database backup in the same bucket:

# Attacker discovers and enumerates a public bucket
aws s3 ls s3://company-user-data --no-sign-request
# Output:
# 2025-07-01 profile_pictures/
# 2025-06-15 database_backup_2025-06.sql.gz
# 2025-05-30 user_export_all.csv
# 2025-04-20 internal_config.json

# Download the database backup
aws s3 cp s3://company-user-data/database_backup_2025-06.sql.gz . --no-sign-request

Bucket discovery methods used by attackers:

  1. Permutation scanning — tools like S3Scanner, Bucket Finder, and cloud_enum guess bucket names from the company name, domain, and product names: company-prod, company-backup, company-data, company-logs, company-assets.
  2. JavaScript bundle analysis — the web application's JavaScript frequently contains direct S3 URLs or bucket references used for uploads and downloads.
  3. Certificate transparency logs — bucket names that use the company's domain may appear in CT logs.
  4. Google dorkingsite:s3.amazonaws.com <company_name> surfaces indexed bucket contents.

Overly permissive IAM policies create a related but distinct class. A bucket may not be publicly accessible but may be accessible to any authenticated AWS principal (any IAM user in any account):

{
  "Effect": "Allow",
  "Principal": "*",
  "Action": "s3:GetObject",
  "Resource": "arn:aws:s3:::company-data/*"
}

"Principal": "*" with no condition means any authenticated AWS user — not just users in your organization — can access the bucket. This is often confused with "requires authentication" but provides essentially no restriction.

Writable public buckets are a critical variant: if s3:PutObject is granted publicly, an attacker can inject malicious files. If the bucket serves static web content or application assets, injecting JavaScript or HTML creates a stored XSS or supply chain attack against every visitor.

Impact

  • Mass data exposure — database backups, user exports, and log archives expose the entire user base's PII, credentials, and financial data.
  • Credential and key leakage — configuration files and .env files in buckets frequently contain database passwords, API keys, and encryption keys.
  • Regulatory breach notification — exposure of PII, health data, or financial records triggers mandatory GDPR, HIPAA, and PCI-DSS breach notification obligations.
  • Supply chain attack — writable public buckets serving static assets allow injection of malicious JavaScript affecting all application users.
  • Ransomware — writable buckets can have their contents deleted or overwritten, destroying backups if they are the only copy.
  • Reputational and financial damage — public bucket breaches are routinely disclosed by security researchers and reported in the media.

Detection

  1. Enumerate company buckets — use S3Scanner (s3scanner scan --bucket <name>), cloud_enum, or Bucket Finder with permutations of the company name, product names, and domain. Test for public read and public write access.
  2. Review bucket policies — for all S3 buckets in your AWS account, check for "Principal": "*" in bucket policies using AWS Config or:
    aws s3api get-bucket-policy --bucket <bucket-name>
    
  3. Audit AWS Block Public Access settings — verify that S3 Block Public Access is enabled at the account and organization level: aws s3control get-public-access-block --account-id <account-id>.
  4. Use Prowler or ScoutSuite — these cloud security posture management tools automatically enumerate all storage buckets across accounts and flag public access, overly permissive policies, and missing encryption.
  5. Check GCS and Azure Blob — test https://storage.googleapis.com/<bucket-name>/ and Azure container URLs for public listing. Tools like GCPBucketBrute and MicroBurst automate this.
  6. Search JavaScript bundles — grep the application's JavaScript for s3.amazonaws.com, storage.googleapis.com, and blob.core.windows.net to discover all referenced buckets.

Remediation

Enable S3 Block Public Access at the organization level. This is the most impactful single control — apply it to every account via AWS Organizations SCPs:

aws s3control put-public-access-block \
  --account-id <account-id> \
  --public-access-block-configuration \
  BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true

Remove public ACLs and overly permissive bucket policies. Audit every bucket policy for "Principal": "*". Replace with least-privilege policies that specify exact IAM roles and users.

Use CloudFront (or equivalent CDN) for public asset delivery. Instead of making a bucket public, serve public content through CloudFront with an Origin Access Identity. The bucket remains private; only CloudFront can access it.

Enable S3 server access logging and CloudTrail data events. Monitor for unexpected access patterns — anonymous requests, bulk downloads, and access from unknown IP ranges.

Apply encryption at rest. Ensure all buckets have default SSE-S3 or SSE-KMS encryption enabled. This protects against physical media exposure and some forms of inadvertent sharing.

Separate bucket roles by sensitivity. Do not store sensitive internal data in the same bucket as public-facing assets. Use separate buckets with distinct access policies for different sensitivity levels.

Ready when you are
Scope a pentest in the next two minutes.
Start scoping