- name
- scope-check
- description
- Validate targets against bug bounty program scope, verify domain/IP ownership, check wildcard rules, and identify out-of-scope exclusions. Use when validating new targets, checking discovered assets, or before testing any endpoint.
- tags
- ["security","scope","bug-bounty","target-validation","domain"]
- triggers
- ["check scope","bug bounty scope","validate target","in scope","scope validation"]
# scope-check
## When to Use
- Before testing any new target or endpoint
- When discovered subdomains need scope validation
- Validating IP addresses against allowed CIDR ranges
- Checking if third-party services are in scope
- Verifying wildcard domain coverage
- Identifying out-of-scope exclusions
## Quick Start
```bash
# Check domain against wildcard scope
target="api.example.com"
echo "$target" | grep -qE "^[a-z0-9-]+\.example\.com$" && echo "IN SCOPE" || echo "OUT"
# Verify DNS resolves
dig +short "$target" | head -1
# Quick CIDR check
python3 -c "import ipaddress; print(ipaddress.ip_address('192.168.1.50') in ipaddress.ip_network('192.168.1.0/24'))"
```
## Core Concepts
### Scope Types
| Type | Format | Example |
| ------------ | -------------- | ----------------- |
| Exact Domain | `domain.com` | `api.example.com` |
| Wildcard | `*.domain.com` | `*.example.com` |
| CIDR Range | `ip/prefix` | `10.0.0.0/24` |
| Single IP | `ip` | `203.0.113.50` |
### Scope Decision Matrix
| Check | IN SCOPE | OUT OF SCOPE |
| ----------------------- | ---------- | -------------- |
| Domain matches wildcard | ✅ Proceed | ❌ Stop |
| IP in CIDR range | ✅ Proceed | ❌ Stop |
| Explicitly excluded | ❌ Stop | N/A |
| Third-party service | ⚠️ Verify | ❌ Likely out |
| Private IP (RFC-1918) | ⚠️ Verify | ❌ Usually out |
## Step-by-Step Process
### Phase 1: Parse Scope Definition
```bash
cat > scope.json << 'EOF'
{
"in_scope": {
"domains": ["*.example.com", "api.example.com"],
"ips": ["203.0.113.0/24"]
},
"out_of_scope": {
"domains": ["*.staging.example.com", "mail.example.com"],
"third_party": ["*.cloudfront.net", "*.amazonaws.com"]
}
}
EOF
jq -r '.in_scope.domains[]' scope.json
jq -r '.out_of_scope.domains[]' scope.json
```
### Phase 2: Domain Validation
```bash
#!/bin/bash
check_domain() {
local target="$1"
local exclusions="mail.example.com staging"
for exc in $exclusions; do
if [[ "$target" == *"$exc"* ]]; then
echo "OUT_OF_SCOPE: Matches exclusion"
return 1
fi
done
if [[ "$target" =~ ^[a-z0-9-]+\.example\.com$ ]]; then
echo "IN_SCOPE: Matches *.example.com"
return 0
fi
echo "OUT_OF_SCOPE: No match"
return 1
}
check_domain "api.example.com"
```
### Phase 3: Wildcard Matching
```python
#!/usr/bin/env python3
def wildcard_match(target, pattern):
"""Check if target matches wildcard pattern"""
if pattern.startswith('*.'):
base = pattern[2:]
if target.endswith(f'.{base}'):
subdomain = target[:-len(base)-1]
return '.' not in subdomain
return target == pattern
print(wildcard_match("api.example.com", "*.example.com")) # True
print(wildcard_match("deep.api.example.com", "*.example.com")) # False
```
### Phase 4: IP/CIDR Validation
```python
#!/usr/bin/env python3
import ipaddress
def ip_in_cidr(ip_str, cidr_str):
"""Check if IP is within CIDR range"""
try:
ip = ipaddress.ip_address(ip_str)
network = ipaddress.ip_network(cidr_str, strict=False)
return ip in network
except ValueError:
return False
def is_private_ip(ip_str):
"""Check RFC-1918 private ranges"""
try:
return ipaddress.ip_address(ip_str).is_private
except ValueError:
return False
print(ip_in_cidr("203.0.113.50", "203.0.113.0/24")) # True
print(is_private_ip("10.0.0.1")) # True
```
### Phase 5: DNS Verification
```bash
#!/bin/bash
verify_dns() {
local target="$1"
local ip=$(dig +short A "$target" | head -1)
if [ -z "$ip" ]; then
echo "❌ DNS failed: No A record"
return 1
fi
echo "✓ Resolves to: $ip"
local cname=$(dig +short CNAME "$target")
if [ -n "$cname" ]; then
echo "⚠️ CNAME: $cname"
case "$cname" in
*cloudfront.net*|*cloudflare*|*akamai*)
echo "⚠️ Third-party CDN - verify scope!"
;;
esac
fi
}
verify_dns "api.example.com"
```
### Phase 6: Full Validation
```python
#!/usr/bin/env python3
import json
import ipaddress
class ScopeValidator:
def __init__(self, scope_file):
with open(scope_file) as f:
self.scope = json.load(f)
def validate(self, target):
try:
ipaddress.ip_address(target)
return self._check_ip(target)
except ValueError:
return self._check_domain(target)
def _check_domain(self, domain):
for exc in self.scope.get('out_of_scope', {}).get('domains', []):
if self._wildcard_match(domain, exc):
return {'status': 'OUT_OF_SCOPE', 'reason': f'Excluded: {exc}'}
for pattern in self.scope.get('in_scope', {}).get('domains', []):
if self._wildcard_match(domain, pattern):
return {'status': 'IN_SCOPE', 'reason': f'Matches: {pattern}'}
return {'status': 'OUT_OF_SCOPE', 'reason': 'No match'}
def _check_ip(self, ip):
ip_obj = ipaddress.ip_address(ip)
if ip_obj.is_private:
return {'status': 'NEEDS_REVIEW', 'reason': 'Private IP (RFC-1918)'}
for cidr in self.scope.get('in_scope', {}).get('ips', []):
if ip_obj in ipaddress.ip_network(cidr, strict=False):
return {'status': 'IN_SCOPE', 'reason': f'In CIDR: {cidr}'}
return {'status': 'OUT_OF_SCOPE', 'reason': 'No matching CIDR'}
def _wildcard_match(self, target, pattern):
if pattern.startswith('*.'):
base = pattern[2:]
return target.endswith(f'.{base}') and target.count('.') == pattern.count('.')
return target == pattern
```
## Examples
### Example 1: Wildcard Domain Check
**Scope**: `*.example.com` (excluding `*.staging.example.com`)
```bash
targets=("api.example.com" "staging.api.example.com" "mail.example.com")
for t in "${targets[@]}"; do
if [[ "$t" == *".staging."* ]]; then
echo "❌ $t - excluded"
elif [[ "$t" =~ ^[a-z0-9-]+\.example\.com$ ]]; then
echo "✓ $t - in scope"
else
echo "❌ $t - out of scope"
fi
done
```
### Example 2: CIDR Range Check
```python
import ipaddress
scope = "192.168.1.0/24"
excluded = "192.168.1.1"
network = ipaddress.ip_network(scope)
for ip in ["192.168.1.50", "192.168.1.1", "10.0.0.1"]:
if ip == excluded:
print(f"❌ {ip} - excluded")
elif ipaddress.ip_address(ip) in network:
print(f"✓ {ip} - in scope")
else:
print(f"❌ {ip} - out of scope")
```
### Example 3: Pre-Test Validation
```bash
#!/bin/bash
pretest_check() {
local target="$1"
echo "=== PRE-TEST: $target ==="
ip=$(dig +short A "$target" | head -1)
[ -z "$ip" ] && echo "❌ DNS failed" && return 1
echo "✓ Resolves: $ip"
if [[ "$ip" =~ ^(10\.|192\.168\.|172\.(1[6-9]|2|3[01])\.) ]]; then
echo "⚠️ Private IP - verify authorization"
fi
cname=$(dig +short CNAME "$target")
[ -n "$cname" ] && echo "⚠️ CNAME: $cname"
[[ "$target" == *".example.com" ]] && echo "✓ In scope" || echo "❌ Out of scope"
}
pretest_check "api.example.com"
```
### Example 4: Third-Party Detection
```bash
target="cdn.example.com"
cname=$(dig +short CNAME "$target" | head -1)
third_parties="cloudfront.net cloudflare akamai fastly amazonaws.com github.io"
for tp in $third_parties; do
if [[ "$cname" == *"$tp"* ]]; then
echo "⚠️ Third-party detected: $tp"
echo " Verify if testing is authorized!"
break
fi
done
```
### Example 5: Bulk Asset Validation
```bash
#!/bin/bash
validate_assets() {
local input_file="$1"
local scope_pattern="$2"
local in_count=0
local out_count=0
while read -r target; do
[ -z "$target" ] && continue
if [[ "$target" =~ $scope_pattern ]]; then
echo "✓ IN: $target"
((in_count++))
else
echo "❌ OUT: $target"
((out_count++))
fi
done < "$input_file"
echo "Summary: $in_count in-scope, $out_count out-of-scope"
}
validate_assets "targets.txt" "^[a-z0-9-]+\.example\.com$"
```
### Example 6: Pre-Exploitation Check
```python
#!/usr/bin/env python3
import socket
import ipaddress
def pre_exploit_check(target, scope_domains, scope_cidrs):
"""Complete pre-exploitation verification"""
result = {"target": target, "checks": [], "safe_to_proceed": False}
domain_ok = any(
target.endswith(f".{d.lstrip('*.')}")
for d in scope_domains if d.startswith('*.')
) or target in scope_domains
result["checks"].append({
"name": "domain_scope",
"passed": domain_ok
GitHubで見る