Under attack? Get incident response help

Cloud

Finding public S3, Azure Blob and GCS storage in an afternoon

How to find buckets and containers that allow anonymous access on AWS, Azure and Google Cloud, then set account-level guardrails that override them.

Also in:TürkçeDeutschFrançaisEspañolItalianoPolskiNederlandsEesti

Illustration: Finding public S3, Azure Blob and GCS storage in an afternoon

Each of the three big providers has a switch above the individual bucket that overrides whatever someone configured below it. Your afternoon has two jobs: find what is already open, then turn those switches on so the next careless policy does nothing. Do them in that order, because the switches will break anything that relies on being public.

What "public" means on each platform

The definitions differ, and the audit has to look for each one.

PlatformWhat makes it publicGuardrail that overrides it
AWS S3ACLs granting access to the AllUsers or AuthenticatedUsers groups, or a bucket policy that is not provably non-publicBlock Public Access, at account or organisation level
Azure BlobAccount allows anonymous access and the container level is set to Container or BlobAllowBlobPublicAccess set to False on the storage account
Google Cloud StorageallUsers or allAuthenticatedUsers in a bucket IAM policy or an object ACLPublic access prevention, per bucket or via the storage.publicAccessPrevention constraint

S3 treats a bucket policy as public until proven otherwise. It counts as non-public only if it grants access to fixed values, with no wildcards or policy variables, such as a specific principal or a set of CIDR blocks via aws:SourceIp. A wildcard principal therefore fails the test.

On Azure, both conditions must hold. If the account disallows anonymous access, the container setting is irrelevant. If the account allows it, a container still stays private until someone sets its level to Container or Blob.

Step 1: find what is open

S3. The AWS guide points to IAM Access Analyzer for S3 for reviewing public buckets, so start there. Then check the four Block Public Access settings on each account: BlockPublicAcls, IgnorePublicAcls, BlockPublicPolicy and RestrictPublicBuckets. Note that GetBucketAcl returns the effective permissions. A bucket with a public ACL and IgnorePublicAcls enabled will show an ACL that hides the real one.

Azure. The portal gives you a count of anonymous requests first. In the storage account, open Monitoring, then Metrics. Use the Blob namespace, metric Transactions, aggregation Sum, and add a filter with Authentication equal to Anonymous.

To see which containers are involved, create a diagnostic setting that sends logs to a Log Analytics workspace. Then run this query, which covers the last seven days:

StorageBlobLogs
| where TimeGenerated > ago(7d) and AuthenticationType == "Anonymous"
| project TimeGenerated, AccountName, AuthenticationType, Uri

The Uri column names the containers and blobs being read. Metrics and logs only show who is reading anonymously, not what is exposed, so an open container nobody has requested stays invisible. Check container access levels as well.

Google Cloud. Inspect bucket IAM policies for roles granted to allUsers or allAuthenticatedUsers. Cloud Asset Inventory shows the policies for all buckets in a project, folder or organisation, which saves you going bucket by bucket. Object ACLs need a separate look, and managed folders have their own IAM policies. Turn on usage logs to see which workloads touch public data. Cloud Audit Logs does not track access to public objects, so it will not help here.

Step 2: switch on the guardrails

S3. AWS recommends enabling all four settings at account level. It also recommends all four on each bucket to satisfy Security Hub control S3.8. For several accounts, use an organisation-level policy. That policy is all-or-nothing, with no per-setting choice, and it overrides account-level settings in the selected member accounts. S3 applies the most restrictive combination across levels, so a bucket cannot weaken what the account enforces.

Apply BlockPublicPolicy at account level in particular. Anyone who can edit a bucket policy can otherwise insert a policy that disables the bucket-level setting. Account-level changes apply to all Regions but may not land everywhere at once. Access point settings can only be set at creation, so check those separately.

Azure. Set AllowBlobPublicAccess to False on each storage account. This overrides every container setting, so you do not need to touch the containers. It requires version 2019-04-01 or later of the Azure Storage resource provider. The user needs Microsoft.Storage/storageAccounts/write, which the Owner, Contributor and Storage Account Contributor roles carry. Keep those assignments narrow.

Google Cloud. Enforce public access prevention on buckets, or set the storage.publicAccessPrevention organisation policy constraint at project, folder or organisation level. Google advises enforcing at the highest level you can. A bucket's state is either enforced or inherited. A bucket with an enforced setting stays enforced even if you later disable the constraint above it.

What will break, and what will not

Plan for breakage, because that is the point of the exercise.

  • S3: The settings do not change existing policies or ACLs. Removing a setting makes anything with a public policy or ACL public again, so clean up the underlying grants as well. Also review identity-based policies and resource policies such as KMS key policies, which Block Public Access does not cover.
  • Azure: Anonymous reads start failing. The code depends on the service version: 401 for versions 2019-12-12 and newer, otherwise 409 when the account disallows anonymous access and 404 when it allows it.
  • Google Cloud: Requests using allUsers fail with HTTP 401 or 403. Existing bindings stay in place but are overridden. Attempts to add them fail with 412 Precondition Failed. Signed URLs are unaffected. Enforcement can take up to 10 minutes, and cached objects can stay public for the Cache-Control lifetime, which defaults to 3600 seconds.

Genuine public content, such as a static website, needs an exception. Azure advises moving it to a separate storage account reserved for anonymous access. On Google Cloud, disable prevention on the specific project that holds the bucket. In S3, customise the individual settings for the buckets that need it.

Where to start

  1. List every AWS account, Azure subscription and Google Cloud project that holds storage, including ones nobody remembers creating.
  2. Run the discovery above: Access Analyzer for S3, the Azure anonymous-request metric and log query, and Cloud Asset Inventory for bucket IAM policies.
  3. For each public finding, decide whether it is deliberate. Move legitimate public content into dedicated accounts or projects.
  4. Enable the account or organisation-level controls: all four S3 settings, AllowBlobPublicAccess set to False, and the storage.publicAccessPrevention constraint.
  5. Re-run the queries a few days later to confirm anonymous requests have dropped to zero, and set an alert on the Azure anonymous-request metric.
  6. If you want an outside check of what remains reachable, our penetration testing service covers cloud exposure, and our consulting team can review your account structure.

How we can help

Consulting and training

We assess where you stand, set priorities with you and train your staff to recognise attacks.

Contact us
AngelForce team

Written by the AngelForce team: security consultants with CEH, LPT Master and CISA certifications who test, monitor and defend systems for organisations across Europe.

Written with AI assistance from public sources listed below, and reviewed by the AngelForce team before publication.

Sources

  1. docs.aws.amazon.com/AmazonS3/latest/userguide/access-control-block-public-access.html
  2. learn.microsoft.com/en-us/azure/storage/blobs/anonymous-read-access-prevent
  3. docs.cloud.google.com/storage/docs/public-access-prevention

Articles about Cloud

Tell us what you need to protect

Describe your environment and what you want to achieve. We will reply by email.

Contact us
info@angelforce.eu +372 5705 2044

AngelForce OÜ · Tallinn, Estonia