
S3 Clones in the Neoclouds
Wiz Research examines S3-compatible object storage offerings from Nebius, Vultr, Lambda Labs, Cloudflare R2, DigitalOcean, and Crusoe, showing how each deviates from AWS S3 security defaults. Findings include providers that expose access/secret keys via list APIs (Vultr), default ACLs that would be public but aren't enforced (Lambda Labs), lack of least-privilege key scoping (Vultr, Crusoe, Lambda Labs), weak or undocumented encryption-at-rest/TLS enforcement, unstructured access-key formats that evade GitHub/secret-scanner detection, and cross-tenant bucket namesquatting risk due to shared global namespaces.
What it is
Wiz Research's field notes on operating S3-compatible object storage across Nebius, Crusoe, Vultr, Lambda Labs, Cloudflare R2, and DigitalOcean using the AWS CLI. The summary already lists the security-default deviations; what it omits are the concrete operational hazards, the per-provider public-bucket mechanics, and one genuinely destructive API surprise.
Things the summary doesn't carry
A clone command that deletes your bucket. On one unnamed clone, aws s3api get-bucket-policy returned the contents of the ListBucket API reshaped to look like a policy response. When the researcher then ran delete-bucket-policy out of curiosity, it deleted the bucket rather than any policy. Treat destructive-sounding S3 verbs against clones as untrusted — the verb you call is not necessarily the action you get.
How each provider exposes buckets publicly (the summary only says "defaults deviate"):
- Nebius — public only via the Nebius API (not web UI, not the S3 API); policies look nothing like S3 policies; anonymous object listing never worked even when docs implied it should.
- Vultr / DigitalOcean — public via the S3
PutBucketAcl. DigitalOcean public buckets are publicly listable, but individual objects still need their own public-read ACL. - Cloudflare R2 — public via Cloudflare API; implements
GetBucketAcl(despite docs saying otherwise) but notPutBucketACLor bucket-policy APIs; public buckets sit behind a per-customer random subdomain and never allow public listing. - Several clones have no public-bucket capability at all, and some force random bucket names, raising the guessing bar.
TLS floor. The summary flags "weak TLS" generically — the page names it: Cloudflare's object storage supports TLS 1.0 by default, versus AWS enforcing TLS 1.2+.
Presigned URLs are inherited automatically. Because they fall out of how the S3 signing API works, every clone supports them whether documented or not (Crusoe documents it; others are silent). Same AWS caveats apply: valid up to 7 days, replayable by anyone who obtains them, and leakable through client-side logging (e.g. browser extensions that record visited URLs).
What to do
- Never run destructive S3 verbs against a clone expecting AWS semantics — probe on throwaway buckets first.
- On Vultr, remember the object-storage list API returns access+secret keys on every call, so treat that API's output as credential-sensitive.
- If you rely on Cloudflare R2, explicitly check/enforce your TLS minimum rather than assuming 1.2+.
- Because clone keys largely lack structured prefixes, your own secret-scanning regexes (not just GitHub's) will miss them — add the per-provider patterns the post tabulates.
Caveats
Findings are point-in-time manual observations; the "delete-bucket-policy deleted the bucket" clone and the single provider with undocumented encryption-at-rest are left unnamed in the excerpt, so verify against your own provider before acting.
Organisations named here
- bucket namesquatting
Technologies named here
- Nebius
- AWS CLI
- GitHub secret scanning
- Crusoe
- Vultr
- Lambda Labs
- Cloudflare R2
- DigitalOcean
- AWS S3
- AWS
- Cloudflare
Techniques named here
- Public bucket exposure
- Bucket squatting
- Presigned URL abuse/leakage
- Credential leakage in source code
- Weak encryption in transit
- Overly broad default ACLs
- Credential over-exposure via API
Related in Cloud & Infra


Orca Security: GenAI Risks in Cloud Environments
.png)
Google API keys keep working after you delete them
