Infrastructure Security

What Is Subdomain Takeover?

A vulnerability where a DNS record (usually a CNAME) points to an external service that is no longer controlled by the domain owner. An attacker can claim the abandoned service and serve their own content on the subdomain, which appears to be part of the legitimate domain.

How It Works

Subdomain takeover exploits the gap between DNS records that still exist and cloud services that have been deleted or abandoned.

Step 1: Stale record creation — Your team creates staging.yourapp.com CNAME yourapp-staging.herokuapp.com to point the staging subdomain to a Heroku app. The staging environment is actively used for months.

Step 2: Service deletion — The project moves to a new hosting platform. The Heroku app yourapp-staging is deleted. A developer removes the Heroku app but forgets to remove the DNS CNAME record from the DNS provider.

Step 3: The stale statestaging.yourapp.com still has a CNAME record pointing to yourapp-staging.herokuapp.com. When anyone requests staging.yourapp.com, the DNS correctly resolves through the CNAME to the Heroku hostname — but Heroku returns "No such app" because the app no longer exists. The domain is now vulnerable.

Step 4: Attacker discovery — The attacker uses tools like subfinder + httpx to enumerate all subdomains of yourapp.com, then checks each for CNAME targets. They identify that yourapp-staging.herokuapp.com returns Heroku's "no such app" error, which is a known takeover fingerprint for Heroku.

Step 5: Service claiming — The attacker creates a new Heroku application and names it yourapp-staging. Heroku allows this because the app name is now unclaimed. The attacker deploys their content to this app.

Step 6: Subdomain control — Any request to staging.yourapp.com now resolves through the CNAME to yourapp-staging.herokuapp.com, which now serves the attacker's content. The attacker controls a subdomain of your legitimate domain. They can serve phishing pages, steal .yourapp.com cookies if they are not scoped tightly, or use the subdomain for email phishing (some spam filters trust subdomains of trusted domains).

Types of Subdomain Takeover

CNAME to Deleted Cloud Service

Most common variant — a CNAME record points to a Heroku, GitHub Pages, Netlify, Render, or similar PaaS hostname that was deleted, allowing the attacker to claim the app name on the platform.

# DNS record that creates vulnerability:
# staging.yourapp.com  CNAME  yourapp-staging.herokuapp.com
# App "yourapp-staging" was deleted — attacker creates it
$ heroku create yourapp-staging
# Now controls staging.yourapp.com

S3 Bucket Takeover

A CNAME points to an S3 bucket that was deleted — attacker creates a new S3 bucket with the exact same name in the same region.

# DNS: files.yourapp.com CNAME yourapp-assets.s3.amazonaws.com
# Bucket deleted — attacker creates s3://yourapp-assets in same region
aws s3 mb s3://yourapp-assets --region us-east-1
# Now controls files.yourapp.com

Dangling A Record

An A record points to a cloud IP address (EC2, DigitalOcean droplet) that was released back to the provider's pool and may be reassigned to another customer.

# DNS: api.yourapp.com  A  54.200.1.100
# EC2 instance terminated — IP released back to AWS pool
# Another AWS customer launches instance, gets 54.200.1.100
# Now controls api.yourapp.com

NS Record Takeover

A subdomain is delegated to external nameservers that the organization no longer controls — attacker registers the expired nameserver domain and controls DNS for the entire delegated zone.

# DNS: partner.yourapp.com  NS  ns1.old-partner.com
# old-partner.com domain expired and available for registration
# Attacker registers old-partner.com and creates ns1.old-partner.com
# Now controls all DNS for partner.yourapp.com

In Laravel Applications

Subdomain takeovers happen when you decommission a service (Heroku, GitHub Pages, S3) but forget to remove the DNS record. Regular DNS audits and continuous monitoring catch stale records before attackers exploit them.

Code Examples

DNS Zone Audit: Stale CNAME vs. Clean Record

Vulnerable

; DNS Zone — VULNERABLE: CNAME pointing to deleted service
; staging.yourapp.com resolves to Heroku but the app no longer exists
staging.yourapp.com.    3600  IN  CNAME  yourapp-staging.herokuapp.com.
docs.yourapp.com.       3600  IN  CNAME  yourapp.github.io.
cdn.yourapp.com.        3600  IN  CNAME  yourapp-assets.s3.amazonaws.com.
; All three may be vulnerable if the target services were deleted

Secure

; DNS Zone — CLEAN: only CNAME records pointing to active services
; Audit by resolving each CNAME target and verifying the service exists

; Option 1: Remove the record entirely when decommissioning
; (staging.yourapp.com CNAME removed because Heroku app was deleted)

; Option 2: If keeping the subdomain, point it to an active service
staging.yourapp.com.    3600  IN  CNAME  yourapp-staging.fly.dev.
; Verify: curl -I https://staging.yourapp.com returns 200, not "No such app"

Real-World Example

Your staging.yourapp.com CNAME points to a Heroku app you deleted. An attacker creates a new Heroku app on that hostname and now controls staging.yourapp.com, which they use for phishing.

Why It Matters

Subdomain takeovers are one of the most underestimated vulnerabilities in web application security. When a subdomain's DNS record points to a third-party service that has been abandoned or deleted, the record continues to exist. An attacker who can register the abandoned service (a Heroku app name, an S3 bucket, a GitHub Pages repository) instantly gains control over content served on that subdomain.

The impact is severe because the subdomain appears to be part of your legitimate domain. An attacker controlling staging.yourapp.com can serve phishing pages that users trust because they are on your domain. They can also potentially steal cookies set on .yourapp.com, serve malicious downloads, or abuse your domain's email reputation.

Laravel teams commonly accumulate vulnerable DNS records over time: staging environments deployed to Heroku or Render and later decommissioned, GitHub Pages sites for documentation that were migrated to another platform, S3 buckets for file storage that were replaced, or feature branch environments deployed to cloud platforms.

The fix is simple: remove DNS records that no longer point to active services. The detection is the hard part — you need to audit every DNS record and verify the service it points to is still active and under your control.

Common Misconceptions

Myth: Subdomain takeover only matters for subdomains we actively use.

Reality: The most dangerous subdomain takeovers target subdomains that were used in the past but forgotten. If a DNS record exists, it is in scope for takeover — regardless of whether your team remembers it.

Myth: We would notice if someone took over our subdomain.

Reality: An attacker who takes over a subdomain can serve content that mirrors your legitimate site, making detection difficult. Continuous DNS monitoring is necessary to detect takeovers promptly.

Myth: Only CNAME records are vulnerable to subdomain takeover.

Reality: While CNAMEs are the most common vector, A records pointing to cloud IP addresses that have been released back to the pool, and NS records pointing to nameservers you no longer control, can also be vulnerable to takeover.

How to Detect This

Audit all your DNS records using your DNS provider's dashboard or `dig yourdomain.com ANY`. For each CNAME record, resolve the target and verify it points to an active service you control: `dig CNAME staging.yourdomain.com`. Use tools like `nuclei` with the subdomain-takeover template (`nuclei -t nuclei-templates/takeovers/ -u yourdomain.com`) to scan for known takeover signatures across common platforms. StackShield continuously monitors all your DNS records and tests CNAME targets for takeover indicators, alerting you when a record points to an unclaimed resource on platforms known to be vulnerable (Heroku, GitHub Pages, Netlify, AWS S3, and others).

How to Prevent This in Laravel

  1. 1

    Audit all DNS records quarterly using your DNS provider's export and verify each CNAME target resolves to an active service you control — `dig CNAME staging.yourapp.com` should resolve to a live, owned service.

  2. 2

    Add "remove DNS record" as a mandatory step in your decommissioning checklist, alongside "delete the cloud service" — the DNS record must be removed BEFORE or simultaneously with the service.

  3. 3

    Use StackShield or `nuclei -t nuclei-templates/takeovers/ -target yourapp.com` to scan for known subdomain takeover fingerprints across Heroku, GitHub Pages, Netlify, AWS S3, and 50+ other platforms.

  4. 4

    Scope session cookies to the specific subdomain they are needed on (`session_domain` in `config/session.php`) rather than the parent domain (`.yourapp.com`) to limit the impact if a subdomain is taken over.

  5. 5

    Implement DNS-as-code using Terraform or similar tools to track the lifecycle of DNS records in version control — this creates a historical record and makes it easier to audit what records exist and why.

Frequently Asked Questions

How do I check if my subdomains are vulnerable to takeover?

List all your DNS records using your provider's export feature or `dig yourapp.com ANY`. For each CNAME record, resolve the target with `dig CNAME subdomain.yourapp.com` and visit the resolved hostname directly. Check for platform-specific "unclaimed" error messages: Heroku shows "There's nothing here, yet", GitHub Pages shows "There isn't a GitHub Pages site here", and S3 shows "NoSuchBucket". These indicate the CNAME target is claimable.

Which cloud services are most commonly involved in subdomain takeovers?

Heroku, GitHub Pages, Netlify, Render, Fly.io, AWS S3, AWS CloudFront, Azure (various services), and FastLy are the most commonly exploited platforms. The `Can I Take Over XYZ` repository (github.com/EdOverflow/can-i-take-over-xyz) maintains an up-to-date list of platforms and their vulnerability status with fingerprints to look for.

How quickly can a subdomain takeover be exploited after the CNAME target is abandoned?

Exploitation can happen within hours. Automated scanners continuously probe for unclaimed hostnames on popular platforms. Once a Heroku app name is deleted, it becomes available to anyone who creates a new app with that name. The attacker doesn't need to know your specific subdomain in advance — they run automated tools to enumerate your subdomains and check each CNAME target for takeover fingerprints, then claim the first available ones.

Does HTTPS prevent subdomain takeover attacks?

No. Let's Encrypt and other CAs issue certificates to anyone who can prove control of a domain via HTTP or DNS challenge. An attacker who takes over `staging.yourapp.com` via a Heroku app can get a valid Let's Encrypt certificate for that subdomain, making their phishing page appear to have a valid padlock. HTTPS indicates encryption, not that the content comes from the legitimate organization. Certificate Transparency monitoring can help you detect unauthorized certificates issued for your subdomains.

Related Terms

Related Articles

Related Fix Guides

Monitor Your Laravel Application's Security

StackShield continuously checks your Laravel application from the outside, catching security issues before attackers find them.

Start Free Trial