Luke a Pro

Luke Sun

Developer & Marketer

šŸ‡ŗšŸ‡¦

Subdomain Takeover

| , 5 minutes reading.

1. Definition

Subdomain Takeover occurs when a subdomain’s DNS record points to an external service (like cloud hosting, CDN, or SaaS platform) that has been deprovisioned or never properly configured. An attacker can claim this unconfigured resource and effectively control the subdomain.

This vulnerability is dangerous because:

  • The attacker controls content under your trusted domain
  • Cookies scoped to the parent domain may be accessible
  • Users trust the subdomain as legitimate
  • Can be used for phishing, credential theft, or malware distribution

2. Technical Explanation

How It Happens:

  1. Company creates blog.example.com pointing to a cloud service (e.g., GitHub Pages, Heroku, AWS S3).
  2. Later, the cloud resource is deleted, but the DNS record remains.
  3. The subdomain now points to an unclaimed resource.
  4. An attacker creates a new resource with the same name on the cloud platform.
  5. The attacker now controls blog.example.com.

Vulnerable DNS Record Types:

  • CNAME Records: blog.example.com CNAME example.github.io - GitHub repo deleted
  • A Records: Pointing to deallocated cloud IPs that can be reassigned
  • NS Records: Delegating to nameservers the attacker can register

Common Vulnerable Services:

ServiceIndicatorTakeover Method
GitHub Pages404 - ā€œThere isn’t a GitHub Pages site hereā€Create repo with matching name
Herokuā€No such appā€Create app with same name
AWS S3ā€NoSuchBucketā€Create bucket with same name
Azureā€404 Web Site not foundā€Claim the resource name
Shopifyā€Sorry, this shop is currently unavailableā€Register the myshopify.com subdomain
Fastlyā€Fastly error: unknown domainā€Add domain to Fastly account

3. Attack Flow

sequenceDiagram
    participant DNS as DNS Server
    participant Attacker
    participant User as Victim User
    participant Cloud as Cloud Provider

    Note over DNS: blog.example.com<br/>CNAME → old-app.herokuapp.com<br/>(Resource deleted)

    Attacker->>Cloud: Check if old-app is available

    Cloud-->>Attacker: Resource name is available

    Attacker->>Cloud: Create new app named old-app

    Cloud-->>Attacker: App created successfully

    Attacker->>Cloud: Deploy malicious content

    User->>DNS: Resolve blog.example.com

    DNS-->>User: CNAME → old-app.herokuapp.com

    User->>Cloud: Request old-app.herokuapp.com

    Cloud-->>User: Attacker controlled content<br/>served under example.com subdomain

    Note over User: User sees legitimate<br/>example.com domain<br/>Trusts the content

4. Real-World Case Study: Vine (Twitter) Subdomain Takeover (2014)

Target: Vine (Twitter’s video platform). Vulnerability Class: Subdomain Takeover via Fastly CDN.

The Vulnerability: Security researcher Detectify discovered that attachments.vine.co had a CNAME record pointing to Fastly CDN, but the Fastly configuration had been removed.

The Attack Scenario:

  1. The subdomain attachments.vine.co pointed to Fastly.
  2. Fastly returned an error indicating the domain was not configured.
  3. Anyone with a Fastly account could claim this domain.
  4. The attacker could then serve arbitrary content on attachments.vine.co.

Potential Impact:

  • Cookie Theft: Vine’s session cookies could potentially be scoped to *.vine.co, meaning the attacker could steal user sessions.
  • Phishing: Users seeing vine.co in the URL would trust the content.
  • OAuth Hijacking: If Vine used this subdomain for OAuth callbacks, attackers could intercept tokens.

Resolution: Twitter was notified through their bug bounty program and promptly removed the dangling DNS record.

5. Detailed Defense Strategies

A. DNS Hygiene

Maintain an accurate inventory of all DNS records.

  • Regular Audits: Periodically review all DNS records and verify they point to active resources.
  • Decommissioning Process: Always remove DNS records BEFORE deprovisioning cloud resources.
  • Documentation: Maintain records of which team owns each subdomain.
# Audit script example
for subdomain in $(cat subdomains.txt); do
  result=$(dig +short $subdomain)
  if [ -z "$result" ]; then
    echo "DANGLING: $subdomain"
  fi
done

B. Automated Monitoring

Use tools to continuously scan for vulnerable subdomains.

  • Tools:
    • subjack - Subdomain takeover detection
    • nuclei - Vulnerability scanner with takeover templates
    • can-i-take-over-xyz - Community-maintained list of vulnerable services
# Using subjack
subjack -w subdomains.txt -t 100 -timeout 30 -o results.txt -ssl

C. Claim Resources Proactively

Even if you don’t use a service, claim the namespace.

  • Strategy: Create placeholder resources on major cloud platforms using your domain name.
  • Example: If you own example.com, claim example on GitHub, Heroku, etc.

D. Use Verified Domain Ownership

Choose cloud services that verify domain ownership.

  • Verification Methods:
    • TXT record verification
    • HTTP file verification
    • Meta tag verification

Services with proper verification prevent attackers from claiming your domains.

Limit the blast radius if a subdomain is compromised.

  • Explicit Domain Scope: Set cookies with explicit domain (no leading dot).
  • Separate Cookie Domains: Use different domains for sensitive cookies.
  • __Host- Prefix: Use __Host- prefix for cookies that should only be set by the host.
# Bad: Accessible by all subdomains
Set-Cookie: session=abc123; Domain=.example.com

# Better: Only accessible by www.example.com
Set-Cookie: session=abc123; Domain=www.example.com

# Best: Host-bound cookie
Set-Cookie: __Host-session=abc123; Secure; Path=/

F. Implement CAA Records

Restrict which Certificate Authorities can issue certificates for your domain.

example.com. CAA 0 issue "letsencrypt.org"
example.com. CAA 0 issuewild "letsencrypt.org"
example.com. CAA 0 iodef "mailto:[email protected]"

This prevents attackers from obtaining SSL certificates for taken-over subdomains.

G. Security Headers on All Subdomains

Even non-production subdomains should have security headers.

Content-Security-Policy: default-src 'self'
X-Frame-Options: DENY
X-Content-Type-Options: nosniff

6. References