Introduction
DNS CNAME records are one of the most common ways to map one domain to another. In a traditional setup, a CNAME simply acts as an alias. If new-app.example.com points to old-app.example.com, DNS resolution transparently redirects traffic and the application continues to work without needing to know about the alias.
For example:
new-app.shashankdubey.in → CNAME → old-app.shashankdubey.in
In most web applications, this works seamlessly because the backend server is configured to respond to multiple hostnames. The server typically does not care which alias was used as long as the request eventually reaches it.
However, Amazon S3 behaves very differently.
When S3 serves content through its virtual-hosted style endpoints, it determines which bucket to serve based on the Host header in the HTTP request. In other words, S3 expects the bucket name to exactly match the hostname used by the client. If the hostname does not correspond to an existing bucket, S3 simply returns an error.
This design makes S3 extremely powerful for static hosting, but it also introduces subtle security pitfalls when DNS is configured incorrectly.
Historically, organizations used CNAME records like assets.example.com → assets.example.com.s3.amazonaws.com, where the subdomain name and bucket name match perfectly, allowing S3 to route requests correctly.
Recently, Amazon S3 introduced the Account Regional Namespace, which allows buckets to be created with predictable suffixes tied to an AWS account and region (e.g. hacking-<ACCOUNTID>-<REGION>-an). While this improves bucket ownership guarantees, organizations sometimes map existing subdomains directly to these new endpoints via DNS, e.g. hacking.k23cs.fun → CNAME → hacking-<ACCOUNTID>-<REGION>-an.s3.<REGION>.amazonaws.com. At first glance this seems correct, but because S3 routes requests based on the Host header, the service will look for a bucket named hacking.k23cs.fun, not the bucket in the CNAME target. That mismatch can create subdomain takeover opportunities.
How S3 Actually Routes Requests
To understand the risk, we need to look at how S3 processes incoming requests.
When a browser visits https://hacking.k23cs.fun, the request sent to the S3 endpoint contains:
GET / HTTP/1.1
Host: hacking.k23cs.fun
Even if DNS resolves to hacking-123456789012-us-east-1-an.s3.us-east-1.amazonaws.com, S3 still reads Host: hacking.k23cs.fun. So S3 attempts to locate a bucket named hacking.k23cs.fun. If that bucket does not exist, S3 returns an error such as NoSuchBucket. This behavior is the root cause behind many S3 subdomain takeover vulnerabilities.
Understanding the New Account Regional Namespace
AWS introduced Account Regional Namespace to simplify bucket creation across regions while preventing bucket name collisions between AWS accounts. The naming format looks like:
<prefix>-<accountID>-<region>-an
Example bucket: hacking-123456789012-us-east-1-an. This guarantees that only the AWS account 123456789012 can create buckets with that suffix. For organizations managing large-scale infrastructure, this is extremely helpful. However, problems arise when DNS is configured without understanding how S3 resolves buckets internally.
Edge case: Does the new feature fix it or complicate it?
What if you want to map your new S3 bucket from the regional namespace to a custom subdomain? You might assume a CNAME from assets.shashankdubey.in to abc-123456789012-us-east-1-an.s3.us-east-1.amazonaws.com would work. It doesn’t. S3 uses the Host header as the bucket name, so you’d have to make your subdomain match the bucket. That means your subdomain would need to be abc-123456789012-us-east-1-an.shashankdubey.in. A bit unwieldy, but okay in theory.
Here’s the catch: the bucket name would also need to be abc-123456789012-us-east-1-an.shashankdubey.in. You can’t create a regional-namespace bucket with that name; the namespace format is fixed. So you’d have to create a generic bucket with that exact name. You’re back in the same trap: a generic bucket name that must exactly match your subdomain, with no real benefit from the regional namespace.
Bottom line: You can’t map a custom subdomain to the new S3 regional namespace. The feature solves naming collisions; it doesn’t give you friendly subdomains for those buckets.
Misconfiguration Scenarios
Three common setups that lead to the same trap: S3 ignores the CNAME target and uses the Host header as the bucket name.
CNAME to Account Regional Bucket
DNS: hacking.k23cs.fun → CNAME → hacking-123456789012-us-east-1-an.s3.us-east-1.amazonaws.com. The expectation is that requests to https://hacking.k23cs.fun will serve content from the bucket hacking-123456789012-us-east-1-an. But S3 searches for a bucket named hacking.k23cs.fun. If that bucket does not exist, an attacker could create it.
Subdomain → Bucket Prefix
Another common configuration: hacking2025.k23cs.fun → hacking2025.s3.amazonaws.com. S3 still reads Host: hacking2025.k23cs.fun and looks for the bucket hacking2025.k23cs.fun. If that bucket does not exist, it becomes potentially claimable. An attacker can run:
aws s3api create-bucket --bucket hacking2025.k23cs.fun
Upload malicious content and instantly control https://hacking2025.k23cs.fun.
Subdomain → Generic S3 Endpoint
Sometimes DNS points directly to s3.amazonaws.com: hacking2026.k23cs.fun → s3.amazonaws.com. S3 still evaluates Host: hacking2026.k23cs.fun, so the bucket it looks for is hacking2026.k23cs.fun. If that bucket does not exist, the subdomain becomes vulnerable.
Realistic Attack Walkthrough
Below is the attack flow from enumeration to takeover in four steps.
Enumerate Subdomains
Attackers use tools like subfinder -d k23cs.fun, amass enum, or assetfinder to discover subdomains such as hacking.k23cs.fun.
Inspect DNS Records
Run dig hacking.k23cs.fun. Result might show: hacking.k23cs.fun CNAME hacking-123456789012-us-east-1-an.s3.us-east-1.amazonaws.com.
Probe the Endpoint
Accessing the domain may return NoSuchBucket or AccessDenied. Both indicate potential S3 routing behavior.
Attempt Bucket Creation
If the bucket does not exist, an attacker may run aws s3api create-bucket --bucket hacking.k23cs.fun. If successful, they control https://hacking.k23cs.fun.
Impact
When an attacker claims a dangling subdomain, the impact goes beyond a broken link. Trust is the weapon: the domain still belongs to you, so users and browsers treat it as legitimate.
Phishing on your brand
Host fake login or payment pages on your subdomain. Users see your domain and hand over credentials.
Malicious scripts
Inject keyloggers, cryptominers, or redirects. Same-origin perception makes detection harder.
OAuth and SSO abuse
Register the subdomain as a redirect URI and steal tokens or session cookies from your IdP.
Supply chain and malware
Serve trojanized assets, poisoned npm/CDN bundles, or malware. Your reputation carries the payload.
How to Prevent This
- Remove orphaned DNS records - If a bucket is deleted, remove its DNS record.
- Ensure bucket names match subdomains - For S3 static hosting, use
subdomain = bucket name, e.g.assets.example.com→assets.example.com.s3.amazonaws.com. - Continuous subdomain takeover scanning - Use tools like
subjack,nuclei, ortko-substo detect potential takeover conditions. - Asset inventory - Maintain visibility over DNS records, S3 buckets, CDN distributions, and cloud endpoints.
Final Thoughts
Amazon S3's Account Regional Namespace is a powerful improvement that simplifies bucket management and prevents cross-account naming conflicts. However, DNS misconfigurations can still create dangerous security gaps.
The core lesson is simple: S3 does not care about your CNAME target. It only cares about the Host header. When those two don't match, a single forgotten DNS record can quietly turn into a subdomain takeover waiting to happen.