home / skills / transilienceai / communitytools / cdn_waf_fingerprinter

This skill identifies CDNs and WAFs from HTTP, DNS, and TLS signals to reveal protection layers and potential exposure.

npx playbooks add skill transilienceai/communitytools --skill cdn_waf_fingerprinter

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
7.9 KB
---
name: cdn-waf-fingerprinter
description: Identifies CDNs (Cloudflare, Akamai, Fastly) and WAFs
tools: Read, Grep
model: inherit
hooks:
  PostToolUse:
    - matcher: "Read"
      hooks:
        - type: command
          command: "../../../hooks/skills/post_output_validation_hook.sh"
---

# 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
```json
{
  "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
```json
{
  "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
```json
{
  "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
```json
{
  "headers": {
    "X-Amz-Cf-Id": true,
    "X-Amz-Cf-Pop": true,
    "Via": "CloudFront"
  },
  "cname_patterns": [
    "cloudfront.net"
  ]
}
```

### Imperva/Incapsula
```json
{
  "headers": {
    "X-Iinfo": true,
    "X-CDN": "Incapsula"
  },
  "cookies": [
    "incap_ses_*",
    "visid_incap_*",
    "nlbi_*"
  ]
}
```

## Inference Logic

```python
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

```json
{
  "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

Overview

This skill identifies Content Delivery Networks (CDNs), Web Application Firewalls (WAFs), DDoS protection, and bot management services by analyzing HTTP headers, cookies, DNS CNAMEs, IP ranges, and TLS/JARM fingerprints. It aggregates signals into weighted detections and produces a prioritized list of likely providers and protections. The output helps pentesters, bug bounty hunters, and security researchers understand edge services and attack surface obfuscation.

How this skill works

The fingerprinter ingests phase-2 raw signals: http_signals (headers and cookies), dns_signals (CNAME records), ip_signals (IP ranges), and tls_signals (JARM and cert issuers). It matches those signals against known CDN, WAF, DDoS, and bot-management patterns, scoring each match and combining evidence. Detection includes header patterns, cookie name matches, CNAME substring checks, IP-range looks, and exact JARM fingerprint comparisons.

When to use it

  • During reconnaissance to identify edge services protecting or caching a target
  • When confirming if a target hides its origin IP behind a CDN/WAF
  • To prioritize targets for exploits that rely on bypassing WAF or caching behavior
  • When triaging inconsistent signals that may indicate multi-CDN or migration
  • As part of automated scanning pipelines for bug bounty and pentest engagements

Best practices

  • Combine multiple signal types (headers + CNAME + JARM) before concluding provider identity
  • Treat low-weight single signals as tentative and highlight higher-weight aggregates
  • Report all plausible providers when signals conflict or indicate chaining
  • Respect rate limits and legal boundaries when collecting HTTP/DNS/TLS data
  • Use IP-range lists and JARM DB updates regularly to reduce false negatives

Example use cases

  • Detect Cloudflare in front of an application by CF-RAY, cf_clearance, and cloudflare server header
  • Find an Akamai presence by edgekey/akamaiedge CNAMEs and Akamai-specific headers
  • Flag Fastly by X-Served-By cache headers and fastly.net CNAME matches
  • Identify bot management like PerimeterX or DataDome via _px* or datadome cookies
  • Uncover CDN chaining when CNAME and header signals point to different providers

FAQ

How reliable are single-signal detections?

Single signals can indicate a provider but are lower confidence; combine headers, cookies, CNAME and JARM evidence for higher accuracy.

What if signals conflict or show multiple providers?

Conflicting signals may indicate CDN chaining, migration, or intermediate services; report all matches and their weights to reflect uncertainty.

Can TLS/JARM fingerprints identify CDNs?

Yes—exact JARM matches can provide strong evidence, but missing or altered JARM values should fall back to header and DNS checks.