Skip to content
Back to skills

Red Cloud Storage Exposure Testing

ASecurity

Offensive storage exposure testing across AWS S3, Azure Blob/ADLS, and GCP Cloud Storage - resolves s3 public access state (Block Public Access, ACLs, signed URLs) before declaring exposure - covers — existence, listing, read, write, overwrite, delete, ACL/policy modification, and signed-URL…

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added November 7, 2026
securitypythongobashawsgcpazuretestingapisecurity

Works with

  • terminal
  • cli
  • api

Security analysis

A100/100

Scanned November 7, 2026

npx -y skills add bitbytelabio/arsenal --skill red-cloud-storage-exposure-testing --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Red Cloud Storage Exposure Testing?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Red Cloud Storage Exposure Testing
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/bitbytelabio-red-cloud-storage-exposure-testing/badge)](https://www.skillsdirectory.com/skills/bitbytelabio-red-cloud-storage-exposure-testing)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: red-cloud-storage-exposure-testing
description: Offensive storage exposure testing across AWS S3, Azure Blob/ADLS, and GCP Cloud Storage - resolves s3 public access state (Block Public Access, ACLs, signed URLs) before declaring exposure - covers — existence, listing, read, write, overwrite, delete, ACL/policy modification, and signed-URL…
domain: red
category: cloud-security
hide: true
license: Apache-2.0
metadata:
  manifest_entry: src/corpus/red-cloud-storage-exposure-testing/SKILL.md
---
# Cloud Storage Exposure Testing (S3 / Azure Blob / GCS)

## Purpose
Test cloud storage for unauthorized access — externally (black-box) or with credentials — proving the exact permission level obtained: existence, listing, read, write, overwrite, delete, or policy modification. Never collapse these into a single "public bucket" status.

## Entry Conditions
- Candidate bucket/container names (from `cloud-attack-surface-discovery`, recon, or credentialed enumeration)
- Anonymous context always; authenticated-low-priv and discovered-credential contexts where available
- Credentialed mode: `s3:GetBucketPolicy`-class read access to evaluate effective configuration

## Discovery Signals
- Bucket hostnames in JS/CNAME/error messages
- Company/domain/project naming seeds (`<company>-backups`, `<domain>-assets`, `<project>-staging`)
- Presigned URLs (scope, expiry, and signature reveal bucket + often account ID)
- Credentialed: `s3api list-buckets`, storage account keys, `gsutil ls`

## Attack Model

Separate the permission levels and prove each independently:

```text
existence      — does the resource exist at all?
listing        — can the caller enumerate object keys?
read           — can the caller retrieve object contents?
write          — can the caller create objects?
overwrite      — can the caller replace existing objects?
delete         — can the caller remove objects?
ACL/policy mod — can the caller rewrite the access policy itself?
signed URLs    — can the caller mint/extend/abuse presigned access?
cross-account  — can another tenant/account principal reach it?
```

## Methodology

### Step 1: Existence and Anonymous Baseline (AWS)
```bash
# Existence: 404 vs AccessDenied (a 403 on anonymous GET means the bucket EXISTS)
curl -sk -o /dev/null -w "%{http_code}\n" https://s3.amazonaws.com/<bucket>          # 404=absent, 403=exists-protected
curl -sk "https://s3.amazonaws.com/<bucket>/" | head -c 200                          # 200 = anonymous LISTING
curl -sk "https://s3.amazonaws.com/<bucket>/known-object-key"                        # object-level read
aws s3 ls s3://<bucket> --no-sign-request                                            # anonymous listing via CLI
```

### Step 2: Effective Access (not policy text)
Before declaring exposure, resolve the actual s3 public access state (Block Public Access, access points, object ACLs) end to end. A policy containing `"Principal": "*"` is only a CANDIDATE. Effective access can still be denied by:
- Block Public Access (account and bucket level)
- policy conditions (`aws:SourceIp`, `s3:authType-*`)
- access point policies
- object-level ACLs
- VPC endpoint policies
- organizational SCPs

Verify the account/bucket configuration directly when credentialed:
```bash
aws s3api get-public-access-block --bucket <bucket>     # and account level
aws s3api get-bucket-policy --bucket <bucket>
```
Prove it: actually list and read. Conversely, `allAuthenticatedUsers` (GCS `allUsers`/`allAuthenticatedUsers`, Azure public container/SAS) is a candidate until a real object is retrieved with the anonymous/authenticated-low context.

### Step 3: Write/Delete Probes (where scope permits)
```bash
# Create a uniquely-named test object — never touch existing data
echo "arsenal-probe-$(date +%s)" > /tmp/probe.txt
aws s3 cp /tmp/probe.txt s3://<bucket>/arsenal-probe-test.txt --no-sign-request
aws s3api put-object --bucket <bucket> --key arsenal-probe-test.txt --body /tmp/probe.txt --no-sign-request
# Overwrite/delete probes only with explicit runtime authorization for state changes
```

### Step 4: Azure Blob
```bash
# Public access: container-level "blob"/"container" publicAccess
curl -sk -o /dev/null -w "%{http_code}\n" "https://<account>.blob.core.windows.net/<container>?restype=container&comp=list"
# SAS tokens: check expiry, permissions (sp=rwdl...), IP scope; try extension/abuse
# Credentialed: az storage container list --account-name <account>
```

### Step 5: GCP Cloud Storage
```bash
curl -sk "https://storage.googleapis.com/<bucket>" | head -c 200            # XML API anonymous listing
gsutil ls -L gs://<bucket>                                                   # if authenticated
# TestIamPermissions is a claim, not proof — follow with actual ls/cp
# Run enumeration BOTH anonymous AND with any Google account (allAuthenticatedUsers grants)
```

### Step 6: Credentialed Configuration Review
In credentialed mode, configuration evidence can itself be a finding when the assessment asks for misconfigurations: public policies without BPA, wildcard principals, over-broad SAS, disabled soft-delete on sensitive data. Distinguish these as configuration findings, not exploit-proven findings.

## Evidence Contract

```text
candidate bucket
→ anonymous request
→ actual private object returned / written / deleted (concrete object name + content class)
→ sensitivity/impact assessment (what data, how sensitive, how much)
→ report at the proven permission level
```

A bucket existing is not a vulnerability. A wildcard policy is not proof. Read/list/write must each be demonstrated. A write is only a finding with the probe object name recorded.

**NOT evidence**: 403 on anonymous GET (existence only), policy text with `Principal:"*"` (candidate), `allAuthenticatedUsers` mention (candidate), tool output (CloudStorage scan) without retrieval

## Common Misses
- Object-level ACLs granting read on a public-in-policy bucket (or vice versa)
- Access points (S3) with policies differing from the bucket policy
- Presigned URL leakage in JS/referers — often grants write or higher
- Azure SAS tokens with excessive permissions/long expiry
- GCS buckets granting `allAuthenticatedUsers` — missed when only anonymous tests ran
- Snapshot/AMI sharing (adjacent storage surfaces): `restorable-by-user-ids all` in credentialed mode
- Region-specific endpoints (s3.eu-west-1.amazonaws.com) when the global endpoint 404s

## False Positives / Non-Findings
- Public-by-design assets (marketing images, public releases) with no sensitive objects
- Existence-only signals (403s)
- Expired presigned URLs
- Buckets belonging to third parties that merely share a naming seed

## Arsenal Tool Strategy
- `terminal_execute` with aws CLI/az/gsutil/curl for direct evidence
- Python for seed-based candidate generation (bounded wordlists)
- GCPBucketBrute optional for anonymous+authenticated enumeration with custom keywords
- Every confirmed level → ledger with object name + sensitivity

## Specialist Handoffs
- Credentials found in bucket contents → `cloud-credential-abuse`
- Bucket serving a web app / origin for CDN → `cloud-attack-surface-discovery` attack model entry
- Credentialed configuration-only findings → configuration assessment mode section of the provider skill

## Stopping Rule
For each candidate: prove existence, then anonymous listing/read, then (where authorized) write. Stop candidate generation once target-derived seeds are exhausted and no new high-confidence names emerge. Do not enumerate unlimited global namespaces.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.