How to Detect AWS Hosting on Any Website: 5 Methods

April 5, 2026 · 10 min read

Amazon Web Services hosts a massive share of the internet. From startups on Elastic Beanstalk to enterprises running multi-region CloudFront distributions, AWS infrastructure is everywhere—but rarely advertised. There’s no “Powered by AWS” badge in the footer.

Whether you’re doing competitive intelligence, security auditing, or technographic prospecting, knowing that a site runs on AWS—and which AWS services it uses—is valuable data. The good news: AWS leaves fingerprints at every layer of the stack, from DNS records to HTTP headers to TLS certificates.

This guide covers five practical methods to detect AWS hosting, explains how to distinguish between CloudFront, S3, ELB, Elastic Beanstalk, API Gateway, and Amplify, and shows how to automate detection at scale with an API.

Why Detect AWS Hosting?

Competitive Intelligence

Knowing a competitor runs on AWS tells you about their infrastructure maturity and budget. A site behind CloudFront with an ALB backend suggests a well-architected deployment. A site serving static assets directly from S3 suggests a simpler setup. These are signals that inform competitive analysis—especially when combined with CDN and hosting provider detection across an entire market segment.

Security and Compliance Auditing

Security teams need to map external attack surfaces. Detecting that a vendor uses AWS API Gateway or Elastic Beanstalk helps you understand what services are exposed. For compliance teams, confirming that a third-party vendor actually hosts in a specific AWS region (verifiable via CloudFront PoP headers) can be part of vendor due diligence.

Method 1: DNS CNAME Records

DNS is the most reliable way to detect AWS hosting. When a company uses an AWS service, they typically create a CNAME record pointing their domain to AWS infrastructure. These records are public, always available, and cannot be hidden without changing providers.

You can check CNAME records with dig:

$ dig www.example.com CNAME +short
d1a2b3c4d5e6f7.cloudfront.net.

That *.cloudfront.net CNAME immediately tells you the site uses Amazon CloudFront. Each AWS service has distinct CNAME patterns:

CloudFront CNAME Patterns

CloudFront distributions always resolve to *.cloudfront.net. The prefix is a unique distribution ID (e.g., d1a2b3c4d5e6f7.cloudfront.net). This pattern is unambiguous—nothing else uses this domain.

$ dig cdn.example.com CNAME +short
d1a2b3c4d5e6f7.cloudfront.net.

Elastic Load Balancer CNAME Patterns

Application Load Balancers (ALBs) and Network Load Balancers (NLBs) resolve to *.elb.amazonaws.com. The full hostname includes the load balancer name, a unique ID, the region, and the service:

$ dig api.example.com CNAME +short
my-app-lb-1234567890.us-east-1.elb.amazonaws.com.

The region identifier (e.g., us-east-1) embedded in the hostname tells you exactly where the application runs.

S3 Static Hosting CNAME Patterns

Sites served directly from S3 buckets use one of two patterns:

# Virtual-hosted style
$ dig static.example.com CNAME +short
static.example.com.s3.amazonaws.com.

# Website endpoint style
$ dig www.example.com CNAME +short
www.example.com.s3-website-us-east-1.amazonaws.com.

The website endpoint variant includes the region. Both patterns are immediately identifiable as Amazon S3. DetectZeStack matches both .s3.amazonaws.com and .s3-website suffixes.

Other AWS Service CNAMEs

AWS ServiceCNAME Pattern
Elastic Beanstalk*.elasticbeanstalk.com
API Gateway*.execute-api.amazonaws.com
AWS Amplify*.amplifyapp.com
Global Accelerator*.awsglobalaccelerator.com

Technical note: DetectZeStack resolves the full CNAME chain, not just the first hop. A domain might CNAME to cdn.company.com, which itself CNAMEs to d1234.cloudfront.net. We follow the chain until we hit a known pattern or an A/AAAA record. For more on this, see DNS-Based Technology Detection: Why Your CDN Can’t Hide.

Method 2: HTTP Response Headers

AWS services inject identifiable headers into HTTP responses. You can inspect them with curl -I:

$ curl -sI https://example.com | grep -iE "x-amz|x-cache|server|via"
X-Amz-Cf-Pop: IAD89-P2
X-Amz-Cf-Id: abc123def456==
X-Cache: Hit from cloudfront
Via: 1.1 abc123.cloudfront.net (CloudFront)

CloudFront Headers

CloudFront adds several identifiable headers to every response:

S3 Headers

Sites served directly from S3 buckets include different headers:

$ curl -sI https://static.example.com/image.png | grep -iE "server|x-amz"
Server: AmazonS3
X-Amz-Request-Id: 7E4D2B6C9F30A150
X-Amz-Id-2: vlR7PnpV2Ce81l0PRw6jlUpck7aO/...

ALB and API Gateway Headers

Application Load Balancers and API Gateway have fewer distinctive headers, but some patterns emerge:

The limitation of HTTP headers is that operators can strip or modify them. A well-configured reverse proxy can remove Server headers entirely. That’s why headers work best as a complement to DNS, not a replacement.

Method 3: IP Address Ranges

AWS publishes its complete IP address ranges as a machine-readable JSON file. You can resolve a domain to its IP address and check whether it falls within an AWS range.

$ dig +short example.com
54.230.45.123

# Download AWS IP ranges
$ curl -s https://ip-ranges.amazonaws.com/ip-ranges.json | \
  jq '.prefixes[] | select(.service=="CLOUDFRONT") | .ip_prefix' | head -5
"120.52.22.96/27"
"205.251.249.0/24"
"180.163.57.128/26"
"204.246.168.0/22"
"111.13.171.128/26"

AWS Publishes Its IP Ranges

The file at ip-ranges.amazonaws.com/ip-ranges.json contains every IP prefix AWS uses, tagged by service and region. You can filter by service name to check specific AWS products:

Mapping IPs to AWS Regions and Services

Each prefix entry includes the region (e.g., us-east-1) and service name. By matching a resolved IP against these prefixes, you can determine not just that a site uses AWS, but which service and region it runs in. This is particularly useful for CloudFront, where the resolved IP tells you which edge PoP is serving the request.

The downside of IP-based detection is maintenance: AWS updates this file regularly as they expand their network. Any local database of ranges needs periodic refreshes to stay accurate.

Method 4: TLS Certificate Analysis

The TLS certificate presented during the HTTPS handshake can reveal AWS hosting. You can inspect it with openssl:

$ echo | openssl s_client -connect example.com:443 2>/dev/null \
  | openssl x509 -noout -issuer -subject
issuer=C=US, O=Amazon, CN=Amazon RSA 2048 M02
subject=CN=example.com

CloudFront Default Certificates

When a CloudFront distribution uses the default certificate (i.e., the *.cloudfront.net domain), the certificate is issued by Amazon. Sites using custom domains with CloudFront typically provision certificates through AWS Certificate Manager (ACM), which also shows “Amazon” as the issuer.

ACM-Issued Certificates

AWS Certificate Manager (ACM) provides free TLS certificates for use with CloudFront, ALB, and API Gateway. These certificates always show “Amazon” as the issuer organization. If you see a certificate issued by “Amazon” or “Amazon RSA 2048 M02” on a site, it’s strong evidence of AWS infrastructure.

DetectZeStack checks the certificate issuer organization during every scan. When the issuer contains “Amazon,” the API reports “Amazon Web Services” in the technologies array with a confidence of 70%. This lower confidence reflects that some organizations may use ACM certificates on non-AWS origins via third-party integrations, though this is uncommon.

Important: TLS certificate analysis works even when a site blocks HTTP requests. The TLS handshake happens before any HTTP traffic, so certificate data is always available. Combined with DNS, this gives you reliable AWS detection for even the most locked-down sites. For more on this, see DNS + TLS Detection vs Browser Extensions.

Method 5: Use the DetectZeStack API

Running dig, curl -I, and openssl manually works for one-off checks. But if you need to scan hundreds of domains, build a monitoring pipeline, or integrate AWS detection into an existing workflow, you need an API.

Quick Demo (No API Key Required)

You can try the detection without signing up. The /demo endpoint is rate-limited to 20 requests per hour per IP, but requires no authentication:

$ curl -s "https://detectzestack.com/demo?url=aws.amazon.com" | jq '.'
{
  "url": "https://aws.amazon.com",
  "domain": "aws.amazon.com",
  "technologies": [
    {
      "name": "Amazon CloudFront",
      "categories": ["CDN"],
      "confidence": 80,
      "source": "dns"
    },
    {
      "name": "Amazon Web Services",
      "categories": ["Cloud hosting"],
      "confidence": 70,
      "source": "tls"
    }
  ],
  "categories": {
    "CDN": ["Amazon CloudFront"],
    "Cloud hosting": ["Amazon Web Services"]
  },
  "meta": {
    "status_code": 200,
    "tech_count": 2,
    "scan_depth": "full"
  },
  "cached": false,
  "response_ms": 312
}

Authenticated Scanning with /analyze

For production use, the /analyze endpoint supports higher rate limits and is available through RapidAPI:

$ curl -s "https://detectzestack.p.rapidapi.com/analyze?url=netflix.com" \
  -H "X-RapidAPI-Key: YOUR_KEY" \
  -H "X-RapidAPI-Host: detectzestack.p.rapidapi.com" | jq '.'

The response includes every detected technology with confidence scores and source indicators. The source field tells you which detection method found each technology: "dns" for CNAME matches, "header" for custom header patterns, "http" for Wappalyzer fingerprints, and "tls" for certificate analysis.

Batch Scanning Multiple Domains

To scan multiple domains in one request, use the /analyze/batch endpoint with a JSON body:

$ curl -s -X POST "https://detectzestack.p.rapidapi.com/analyze/batch" \
  -H "X-RapidAPI-Key: YOUR_KEY" \
  -H "X-RapidAPI-Host: detectzestack.p.rapidapi.com" \
  -H "Content-Type: application/json" \
  -d '{"urls": ["stripe.com", "twitch.tv", "imdb.com"]}' | jq '.'

The batch endpoint accepts up to 10 URLs per request and returns results for each domain alongside summary statistics. This is useful for scanning a competitor list or enriching a CRM with infrastructure data.

What the API Returns for AWS-Hosted Sites

Technologies Array and Categories Breakdown

When DetectZeStack detects AWS services, each one appears as a separate entry in the technologies array with its own confidence score:

Technology NameCategoriesConfidenceSource
Amazon CloudFrontCDN80–90%dns / header
Amazon S3Cloud hosting80%dns
AWS Elastic BeanstalkPaaS80%dns
AWS ELBCloud, Load Balancer80%dns
AWS API GatewayCloud, API Gateway80%dns
AWS AmplifyPaaS, Hosting80%dns
AWS Global AcceleratorCloud, Load Balancer80%dns
Amazon Web ServicesCloud hosting70%tls

The categories object in the response groups these by function, making it easy to filter for CDN vs. PaaS vs. general cloud hosting.

Understanding DNS-Layer Detection vs HTTP-Layer Detection

DNS-layer detection (confidence 80%) works even when a site blocks HTTP requests, returns CAPTCHAs, or times out. In those cases, DetectZeStack returns a scan_depth: "partial" response with the AWS services detected via DNS and TLS only.

HTTP-layer detection (confidence 90–100%) provides additional confirmation when the site responds. CloudFront’s X-Amz-Cf-Pop header, for example, is matched at 90% confidence by DetectZeStack’s custom header signatures. When both DNS and HTTP layers detect the same service, you get the highest-confidence result.

Building an AWS Detection Pipeline in Python

Here’s a practical example: scan a list of domains and extract only those hosted on AWS, writing the results to a CSV file.

import requests
import csv
import time

API_URL = "https://detectzestack.p.rapidapi.com/analyze"
HEADERS = {
    "X-RapidAPI-Key": "YOUR_KEY",
    "X-RapidAPI-Host": "detectzestack.p.rapidapi.com"
}

AWS_TECH_NAMES = {
    "Amazon CloudFront", "Amazon S3", "Amazon Web Services",
    "AWS Elastic Beanstalk", "AWS ELB", "AWS API Gateway",
    "AWS Amplify", "AWS Global Accelerator"
}

domains = ["stripe.com", "twitch.tv", "imdb.com", "netflix.com"]

with open("aws_hosts.csv", "w", newline="") as f:
    writer = csv.writer(f)
    writer.writerow(["domain", "aws_services", "confidence"])

    for domain in domains:
        resp = requests.get(API_URL, headers=HEADERS, params={"url": domain})
        data = resp.json()

        aws_techs = [
            t for t in data.get("technologies", [])
            if t["name"] in AWS_TECH_NAMES
        ]

        if aws_techs:
            services = ", ".join(t["name"] for t in aws_techs)
            max_conf = max(t["confidence"] for t in aws_techs)
            writer.writerow([domain, services, max_conf])
            print(f"{domain}: {services} (confidence: {max_conf}%)")
        else:
            print(f"{domain}: no AWS detected")

        time.sleep(0.5)  # respect rate limits

This script integrates directly with the API and produces a clean CSV output. For a more complete tutorial covering error handling and batch processing, see Detect Any Website’s Tech Stack with Python.

Conclusion and Next Steps

AWS leaves fingerprints at every layer of the stack. DNS CNAME records are the most reliable signal—they cannot be hidden without changing providers. HTTP headers provide additional confirmation, especially the X-Amz-Cf-Pop and Server: AmazonS3 headers. TLS certificates from Amazon Trust Services confirm AWS infrastructure even when HTTP access is blocked. IP range lookups serve as a final verification layer.

For one-off checks, dig and curl are sufficient. For scanning at scale—competitive analysis across a market, lead enrichment, or continuous security monitoring—the DetectZeStack API combines all four methods into a single request with structured, machine-readable output.

Get Your Free API Key

100 requests per month, no credit card required. Detect AWS services, CDN providers, frameworks, and 7,200+ technologies.

Get Your Free API Key

Related Reading

Get API updates and tech detection tips

Join the mailing list. No spam, unsubscribe anytime.