CDN/WAF Fingerprinter Skill
Purpose
Identify Content Delivery Networks (CDNs), Web Application Firewalls (WAFs), and DDoS protection services from HTTP headers, DNS records, and TLS fingerprints.
Input
Raw signals from Phase 2:
http_signals - CDN/WAF-specific headers, cookies
dns_signals - CDN CNAME delegations
ip_signals - CDN IP ranges
tls_signals - JARM fingerprints, certificate issuers
Technology Categories
Content Delivery Networks
| CDN |
Detection Signals |
Weight |
| Cloudflare |
CF-RAY header, cf-* cookies, cloudflare-nginx server |
45 |
| Akamai |
X-Akamai-, Akamai- headers, akamaiedge.net CNAME |
45 |
| Fastly |
X-Served-By: cache-*, Fastly headers |
45 |
| AWS CloudFront |
X-Amz-Cf-Id, cloudfront.net CNAME |
45 |
| Azure CDN |
X-Azure-Ref, azureedge.net CNAME |
40 |
| Google Cloud CDN |
Via: google, X-GFE-* headers |
40 |
| Cloudinary |
cloudinary.com URLs |
35 |
| imgix |
imgix.net URLs |
35 |
| KeyCDN |
X-Edge-IP, keycdn.com |
35 |
| StackPath |
X-HW headers, stackpath.com |
35 |
| BunnyCDN |
X-Bunny-* headers |
35 |
Web Application Firewalls
| WAF |
Detection Signals |
Weight |
| Cloudflare WAF |
CF-RAY, cf_clearance cookie |
40 |
| AWS WAF |
X-Amz-Cf-Id with WAF rules |
35 |
| Akamai Kona |
Akamai-* WAF headers |
40 |
| Imperva/Incapsula |
X-Iinfo, incap_ses_* cookies |
45 |
| Sucuri |
X-Sucuri-ID, sucuri.net |
40 |
| ModSecurity |
Server: Apache + ModSecurity patterns |
35 |
| F5 BIG-IP |
BIGipServer cookie |
40 |
| Barracuda |
barra_counter_session cookie |
35 |
| Fortinet FortiWeb |
FORTIWAFSID cookie |
40 |
DDoS Protection
| Service |
Detection Signals |
Weight |
| Cloudflare |
CF-RAY, __cf_bm cookie |
40 |
| AWS Shield |
CloudFront + Shield indicators |
35 |
| Akamai Prolexic |
Akamai headers |
35 |
| Arbor Networks |
Specific patterns |
30 |
| Project Shield |
Google infrastructure |
35 |
Bot Management
| Service |
Detection Signals |
Weight |
| Cloudflare Bot Management |
__cf_bm cookie |
40 |
| PerimeterX |
_px* cookies |
40 |
| DataDome |
datadome cookie |
40 |
| Shape Security |
Shape patterns |
35 |
| Kasada |
Kasada patterns |
35 |
| Arkose Labs |
Arkose patterns |
35 |
Detection Patterns
Cloudflare
{
"headers": {
"CF-RAY": true,
"CF-Cache-Status": true,
"Server": "cloudflare"
},
"cookies": [
"__cfduid",
"cf_clearance",
"__cf_bm"
],
"cname_patterns": [
"cdn.cloudflare.net"
],
"ip_ranges": "103.21.244.0/22, 103.22.200.0/22, ...",
"jarm_hash": "29d29d15d29d29d00042d42d000000cd19c7d2c21d91e77fcb9e7a8d6d1d8c"
}
Akamai
{
"headers": {
"X-Akamai-Transformed": true,
"X-Akamai-Session-Info": true,
"X-Akamai-Pragma-Client-IP": true,
"Akamai-Origin-Hop": true
},
"cname_patterns": [
"edgekey.net",
"edgesuite.net",
"akamaiedge.net",
"akamaized.net"
]
}
Fastly
{
"headers": {
"X-Served-By": "cache-",
"X-Cache": true,
"X-Cache-Hits": true,
"Fastly-Debug-Digest": true,
"X-Timer": true
},
"cname_patterns": [
"fastly.net",
"fastlylb.net"
]
}
AWS CloudFront
{
"headers": {
"X-Amz-Cf-Id": true,
"X-Amz-Cf-Pop": true,
"Via": "CloudFront"
},
"cname_patterns": [
"cloudfront.net"
]
}
Imperva/Incapsula
{
"headers": {
"X-Iinfo": true,
"X-CDN": "Incapsula"
},
"cookies": [
"incap_ses_*",
"visid_incap_*",
"nlbi_*"
]
}
Inference Logic
def fingerprint_cdn_waf(signals):
results = []
# Header-based Detection
for cdn in CDN_PATTERNS:
matches = 0
evidence = []
for header, expected in cdn.headers.items():
if header in signals.http_signals.headers:
if expected == True or expected in signals.http_signals.headers[header]:
matches += 1
evidence.append({
"type": "http_header",
"value": f"{header}: {signals.http_signals.headers[header]}"
})
if matches > 0:
results.append({
"name": cdn.name,
"category": cdn.category,
"signals": evidence,
"total_weight": cdn.base_weight + (matches * 5)
})
# Cookie-based Detection
for waf in WAF_PATTERNS:
for cookie in signals.http_signals.cookies:
for waf_cookie in waf.cookies:
if waf_cookie in cookie or fnmatch(cookie, waf_cookie):
results.append({
"name": waf.name,
"category": "WAF",
"signals": [{
"type": "cookie",
"value": f"Cookie pattern: {cookie}"
}],
"total_weight": waf.weight
})
break
# CNAME-based Detection
for cname in signals.dns_signals.cname_records:
for cdn in CDN_PATTERNS:
for pattern in cdn.cname_patterns:
if pattern in cname.target:
add_if_not_exists(results, cdn.name, "CDN", {
"type": "dns_cname",
"value": f"CNAME → {cname.target}"
}, cdn.weight)
# JARM Fingerprint Detection
if signals.tls_signals.jarm_hash:
for cdn in JARM_DATABASE:
if signals.tls_signals.jarm_hash == cdn.jarm_hash:
add_if_not_exists(results, cdn.name, cdn.category, {
"type": "jarm_fingerprint",
"value": f"JARM match: {signals.tls_signals.jarm_hash}"
}, 40)
return results
Output
{
"skill": "cdn_waf_fingerprinter",
"results": {
"technologies": [
{
"name": "Cloudflare",
"category": "CDN",
"signals": [
{
"type": "http_header",
"value": "CF-RAY: 7a1b2c3d4e5f6g7h-IAD",
"weight": 40
},
{
"type": "http_header",
"value": "Server: cloudflare",
"weight": 35
},
{
"type": "cookie",
"value": "__cf_bm cookie present",
"weight": 30
}
],
"total_weight": 105,
"additional_services": ["Bot Management", "DDoS Protection"]
},
{
"name": "Cloudflare WAF",
"category": "WAF",
"signals": [
{
"type": "cookie",
"value": "cf_clearance cookie present",
"weight": 35
}
],
"total_weight": 35
}
],
"security_summary": {
"cdn_provider": "Cloudflare",
"waf_enabled": true,
"waf_provider": "Cloudflare WAF",
"ddos_protection": "Cloudflare",
"bot_management": "Cloudflare Bot Management"
},
"cache_behavior": {
"cache_status_header": "CF-Cache-Status",
"observed_statuses": ["HIT", "MISS", "DYNAMIC"]
}
}
}
Security Implications
CDN Behind WAF
Cloudflare (CDN + WAF) → Origin Server
- All traffic passes through Cloudflare
- WAF rules applied at edge
- Origin IP potentially hidden
Multiple CDN Layers
CDN1 (Cloudflare) → CDN2 (CloudFront) → Origin
- Possible for different purposes
- Content caching vs security
Error Handling
- Multiple CDN signals: May indicate CDN chain or migration
- Conflicting WAF signals: Report all possibilities
- Missing JARM: Fall back to header/cookie detection