All Articles
Cloud Security
AWS Security
DevSecOps
S3
Cloud Architecture

Bucket Namespace Hijacking: How Global S3, GCS and Azure Names Leak Data

Cloud bucket names live in a global pool and return to it on delete. How namespace hijacking works, the research that proved it, and the 2026 fixes for lean teams.

Avinash S
July 30, 2026
13 min read
Illustration for Bucket Namespace Hijacking: How Global S3, GCS and Azure Names Leak Data, covering Cloud Security, AWS Security, DevSecOps

Every cloud storage bucket you have created lives in a namespace shared with every other customer of that provider. The name is not scoped to your account, project or organisation. It is a first-come identifier in a global pool, and when you delete a bucket the name goes straight back into that pool for anyone to claim.

That single design fact drives a family of attacks most pre-seed and seed teams have never modelled. Not a misconfiguration you fix with a checkbox, and not a CVE you patch. A structural property of how cloud object storage has worked since 2006, which turns deleted buckets into permanent liabilities and predictable bucket names into pre-registerable attack surface.

This post covers how the attack family works, the public research that proved it at scale, what AWS shipped in 2026 to fix it structurally, and what a two-engineer startup should do this week. Generic articles frame this as "S3 bucket takeover" and stop at abandoned static websites. That undersells it. The interesting variants hit CI/CD, audit logs, and infrastructure-as-code deployments running with administrative privileges.

Quick context: the namespace, and what changed in 2026

AWS documents the property plainly. General purpose S3 buckets exist in a global namespace where each name must be unique across all AWS accounts in all Regions within a partition, and the AWS namespace documentation states that deleting a global bucket makes the name available again for anyone to re-create. The same doc carries the warning most teams miss: do not depend on bucket naming conventions for availability or security verification.

Google Cloud is identical in shape. Its bucket documentation notes that names live in a single global namespace and that after deletion anyone can reuse the name, typically within seconds. Azure narrows the exposure to storage account names, since containers are account-scoped.

Two things make this a 2026 topic rather than a 2019 one. In June 2026 the Cloud Security Alliance published research treating global namespace hijacking as a systemic cross-provider risk rather than a set of one-off bug reports. And AWS shipped account regional namespaces in March 2026, the first real structural fix any provider has offered. There is now something to turn on, which makes this a configuration task, not an awareness problem.

1. The core mechanic: a name with no proof of ownership

When your code, your Terraform, your CI job or your CNAME record references a bucket by name, it is trusting a string. There is no binding between that string and the account that owned it when the reference was written. If ownership changes, every reference silently follows the name to its new owner.

Compare this to domain names, which is the mental model most engineers accidentally apply. A lapsed domain goes through expiry, a redemption grace period and pending-delete before anyone else can register it, and WHOIS gives you an audit trail. Bucket names have none of that. AWS confirms the name returns to the pool on delete; Google measures the gap in seconds.

So a bucket name is not a resource identifier, it is a claim. Takeaway: treat every bucket name your organisation has ever used as a permanent identifier that must be either retained or de-referenced everywhere, never simply deleted.

2. Abandoned bucket takeover, proven at scale for 420 dollars

In February 2025, researchers at watchTowr re-registered roughly 150 abandoned S3 buckets that had served software distribution assets for government agencies, Fortune 500 companies, military organisations and open source projects. Total cost, as reported at the time, was 420.85 US dollars.

Over two months those buckets received more than eight million requests for Windows, Linux and macOS executables, virtual machine images, JavaScript files, CloudFormation templates and SSL VPN server configurations. Requesting networks included NASA, other US and UK government bodies, military networks and Fortune 100 organisations. The researchers served benign responses. An attacker would not have.

Read that inventory again, because it is the point. CloudFormation templates and VPN configurations fetched from a bucket someone else now owns is not defacement, it is code execution and network access. This scales because abandonment is normal: a project is retired, the bucket is cleaned up, and references in installers, docs, Helm charts and post-install scripts stay live for years.

Takeaway: before deleting any bucket, grep your repositories, docs and published artifacts for the name. If you cannot prove zero references, keep the empty bucket. An empty S3 bucket costs nothing and permanently denies the name to everyone else.

3. Shadow resources: claiming buckets you have not created yet

The second variant does not need you to delete anything. It needs your bucket name to be predictable before you create it.

At Black Hat USA 2024, Aqua Security disclosed the Shadow Resource attack vector and the Bucket Monopoly problem. Several AWS services, when first enabled in a Region, automatically created an S3 bucket whose name followed a fixed template including the caller's AWS account ID. Account IDs are not secret. An attacker who learned yours could pre-create those buckets in every Region you had not yet used, then wait.

When the victim later enabled the service there, it wrote to, and in some cases executed content from, a bucket the attacker already owned. Aqua reported the pattern across AWS Glue, EMR, SageMaker, CloudFormation and Service Catalog, and AWS remediated the affected services. In the worst case the path ran to creating an admin user in the victim account.

The specific bugs are fixed. The class is not, because the ingredients are generic: any tool that derives a bucket name deterministically from a value an attacker can learn is exposed the same way. That includes your own internal tooling that names buckets company-env-service-logs.

Takeaway: audit every place your automation constructs bucket names from non-secret inputs. Append a random GUID, which is what the AWS namespace guidance recommends, or move to account-scoped names as in section 7.

4. The CDK bootstrap bucket, which is the one that hits startups

This variant is the most likely to apply to a pre-seed team right now, because the affected tool is how many startups deploy by default.

The AWS CDK bootstrap process creates a staging bucket for assets and templates. Aqua's follow-up research on CDK bootstrap risk showed the name followed the pattern cdk-{qualifier}-{description}-{account-id}-{region}, with the default qualifier a fixed string, hnb659fds. Almost nobody changes it, so the staging bucket name is fully derivable from an account ID.

An attacker who pre-claims that name can place content CDK later trusts during deployment, and CDK deployments run with the elevated permissions the bootstrap roles grant. The researchers reported a path to full account takeover; the CSA paper puts measured exposure at 81 of 38,560 analysed accounts, roughly one percent of CDK users.

The fix landed in CDK v2.149.0, which added a condition to the file publishing role so it only trusts buckets in your own account. The trap is the upgrade semantics: updating the CDK CLI does not fix an environment bootstrapped by an older version. You must re-run cdk bootstrap on 2.149.0 or later.

Takeaway: if your account was bootstrapped before July 2024, upgrade the CDK and re-bootstrap every account and Region today. A fifteen-minute job with an account-takeover ceiling is the best fix-to-risk ratio you will find all quarter.

5. Telemetry hijack: pointing your audit logs at an attacker

This variant flips the direction of trust. Instead of you reading from a hijacked bucket, you write to one.

CloudTrail, VPC flow logs, load balancer access logs, GCS sink destinations and Azure diagnostic settings all write to a destination named at configuration time. The CSA research describes active stream hijacking: an adversary who can delete the destination bucket, or who finds it already deleted while the logging configuration still references the name, recreates it under their own control. Your logs keep flowing, your dashboards look healthy, and the data lands somewhere else.

How does your infrastructure stack up?

Take the 2-min security quiz →

Worse than a data leak in two ways: your audit trail is now held by the party you would use it to investigate, and the pipeline reports success, so nothing alerts.

Takeaway: verify every logging destination is a bucket in an account you own right now, not one you believe you own. Add aws:ResourceAccount conditions to the relevant policies, enable delete protection on log destination buckets, and alarm on log volume dropping to zero, which is your independent signal that the pipe moved.

6. Dangling DNS: the CNAME that outlives the resource

The DNS variant is the oldest and still the most common, because DNS records and cloud resources have separate lifecycles and separate owners in most companies.

Microsoft documents the mechanics precisely for Azure subdomain takeover. You point a CNAME at a resource FQDN such as abc.blob.core.windows.net, the resource is deprovisioned, the CNAME stays, and an attacker who provisions a resource with the same name receives traffic for your subdomain. The same shape applies to S3 website endpoints and GCS custom domains.

Microsoft's list of consequences is worth taking seriously: loss of content control on your brand, harvesting of session cookies that web apps commonly scope to all subdomains, phishing from a genuinely legitimate hostname, and the attacker's ability to obtain a valid TLS certificate for the hijacked name. A padlock in the browser proves nothing about who owns the subdomain.

Takeaway: make "remove the DNS record" a required decommission step, and run a scheduled job that resolves every CNAME in your zones and confirms the target still belongs to you. Microsoft ships a PowerShell tool called Get-DanglingDnsRecords for the Azure side; on AWS and GCP a short script over your hosted zones gets the same coverage.

7. The 2026 structural fix: account regional namespaces on S3

Everything above is mitigation. This is the first control that removes the root cause, and the most important section here for anyone starting new infrastructure in 2026.

AWS now supports creating general purpose buckets in an account regional namespace, a reserved subdivision of the global namespace that only your account can create buckets in. Names take the form prefix-accountId-region-an. AWS states these buckets can never be re-created by another account, and that if another account attempts to use your suffix the CreateBucket call is rejected. All S3 features work and applications need no changes.

Better still, you can make it mandatory. The s3:x-amz-bucket-namespace condition key lets you deny s3:CreateBucket unless the request sets the namespace to account-regional, as an IAM, Resource Control or Service Control Policy. CloudFormation supports it through a BucketNamespace property and a BucketNamePrefix that appends the suffix for you.

Two caveats before you write the SCP. The suffix consumes part of the 63 character limit, leaving roughly 37 characters for your prefix. And the namespace is not available in the Middle East (Bahrain) and Middle East (UAE) Regions, so plan an exception path there rather than discovering it mid-deployment.

Takeaway: put the SCP in place now so every new bucket is born safe, then migrate legacy buckets on their own schedule. Enforcement at creation time is what stops this from re-accumulating.

8. Bucket owner condition: the guard for buckets you do not own

Section 7 protects the buckets you create. This one protects the calls you make, because a hijacked name only pays off when someone reads from or writes to it.

S3 supports a bucket owner condition: pass the expected owner account ID with the request and S3 fails the call if the bucket belongs to someone else. In the CLI that is --expected-bucket-owner, in the API the x-amz-expected-bucket-owner header. At the policy layer, the aws:ResourceAccount and s3:ResourceAccount condition keys restrict a principal or a VPC endpoint to buckets owned by specific accounts, per AWS guidance on limiting access by bucket owner.

This converts the failure mode from silent to loud. Without it, a hijacked bucket returns 200 and your pipeline carries on with attacker-supplied content. With it, the request fails with an ownership error and someone gets paged. Practitioner opinion: for an early-stage team the VPC endpoint policy version is the highest-leverage control here, because it covers every workload in the VPC at once without touching application code.

Takeaway: add an aws:ResourceAccount allowlist to your S3 VPC endpoint policy covering your own accounts plus the third-party accounts you legitimately read from, and set the expected-owner parameter in any build script that fetches artifacts from a bucket.

9. What GCP and Azure give you, and what they do not

Neither provider has shipped an equivalent of account regional namespaces, so the controls are partial. Knowing which one you have matters.

On Google Cloud, soft delete is the main brake. It launched in March 2024 with a seven day retention duration applied to new and existing buckets, configurable from 7 to 90 days, and Google's writeup covers restoring buckets and objects within the window. That is a recovery window, not namespace protection: once retention lapses, the name is claimable again. GCS also requires domain ownership verification for buckets named after a domain, which is a real ownership binding and worth using for anything customer-facing.

On Azure, the useful structural property is that containers are scoped to the storage account, so only the account name sits in the global pool. Azure also reserves the DNS name of some deleted resources for a period during which only subscriptions in the original Entra tenant can reclaim it, and offers DNS alias records plus App Service asuid TXT verification. Coverage is uneven across services, so read the Microsoft guidance per resource type rather than assuming.

Takeaway: on GCP, confirm soft delete is on with an acceptable retention window for log and artifact buckets, and use domain-named buckets where customers see the hostname. On Azure, protect the storage account name and put delete locks on any resource with a custom DNS entry pointing at it.

10. The one-hour audit for a two-engineer team

None of this needs a platform team. Here is the sequence I would run, in priority order, for a startup with a handful of AWS accounts. Ordering matters more than completeness: CDK bootstrap and dangling DNS are where the account-takeover severity lives, and the rest is hardening.

  • Minutes 0 to 15: check the CDK bootstrap version in every account and Region. If it predates v2.149.0, upgrade and re-bootstrap. Highest severity, lowest effort.
  • Minutes 15 to 30: list every CNAME in your DNS zones that resolves to a cloud storage or platform hostname. For each, confirm the target resource exists and is yours. Delete the rest.
  • Minutes 30 to 40: enumerate every logging and backup destination bucket across CloudTrail, flow logs, ALB logs and CI artifacts. Confirm each is an account you own, and add a zero-volume alarm.
  • Minutes 40 to 50: grep your repositories, installers and public documentation for hardcoded bucket names and hostnames. Any name you no longer own is a live incident, not a cleanup ticket.
  • Minutes 50 to 60: apply the s3:x-amz-bucket-namespace SCP so new buckets land in your account regional namespace, and add the aws:ResourceAccount allowlist to your S3 VPC endpoint policy.

Summary: the attack family at a glance

VariantTriggerWorst casePrimary control
Abandoned bucket takeoverYou deleted a bucket others still referenceSupply chain code executionNever delete; retain empty bucket
Shadow resource land grabService auto-creates a predictable bucket namePrivilege escalation in your accountGUID or account regional names
CDK bootstrap hijackBootstrapped before CDK v2.149.0Full account takeoverRe-bootstrap on 2.149.0 or later
Telemetry hijackLog destination deleted or recreatedAudit trail delivered to attackeraws:ResourceAccount plus zero-volume alarm
Dangling DNSCNAME outlives the resourceCookie theft and phishing on your brandDNS record in decommission checklist
Wrong-bucket writesName typo or ownership changeSilent data disclosureexpected-bucket-owner on every call

What to do at your stage

Pre-seed, one to five engineers: do the CDK re-bootstrap and the DNS sweep. That is it. Both are bounded, both close the account-takeover paths, and neither needs process. Adopt account regional namespaces for new buckets so the debt never accumulates.

Seed, five to twenty engineers: add enforcement. The SCP on bucket creation, the aws:ResourceAccount allowlist on your VPC endpoint, delete protection on log buckets, and a pre-deletion checklist requiring a reference search. Enough people create buckets now that policy beats discipline.

Series A and beyond: treat bucket names as a tracked inventory with owners, the way you track domains and certificates. Add namespace hijacking to your threat model, run continuous dangling-DNS detection, and audit third-party bucket references in your dependency tree, which is where the CSA research found abandoned references inside package ecosystems.

If you want someone to run this audit with you

MatrixGard runs a free 20-minute cloud posture review for pre-seed and seed founders. Bring your AWS or GCP setup and we will walk the namespace exposure specifically: CDK bootstrap version, dangling CNAMEs, log destinations, hardcoded bucket references. My honest read, no NDA required for the first conversation. Send a note.

Avinash S is the founder of MatrixGard. Fractional DevSecOps for pre-seed and seed startups across India, the GCC, Singapore, the UK, and the US. Almost a decade of building, breaking, and securing cloud infrastructure for fintech, healthtech, and SaaS workloads.


Methodology note. Provider behaviour is taken from current vendor documentation: the AWS S3 namespaces and bucket owner condition pages, GCS bucket docs, and Microsoft's subdomain takeover guidance. Attack disclosures and figures are attributed to their sources: watchTowr via The Register for the 150 bucket and 420.85 dollar figures, Aqua Security for Shadow Resource and CDK bootstrap, and the Cloud Security Alliance paper of June 2026 for the cross-provider framing and CDK exposure counts. The audit sequence and stage recommendations are practitioner judgement, not vendor guidance. Region availability and defaults change; verify against current provider docs before building policy on them.

MatrixGard

Ready to close the gaps?

MatrixGard finds what your team missed. Not because they're bad, because they're too close to the problem.

Book a free review