Can someone impersonate your domain via email?
11-layer email security scanner with interaction-aware scoring, spoofability verdict, and copy-paste remediation.
Made by bau1u
Quick Start • 11 Layers • Scoring • vs Competitors • Usage
Most DMARC checkers and email security tools ask: "Is your DNS configured correctly?"
SpoofScore asks a different question:
"Can an attacker send email as you, right now?"
An open-source email spoofing scanner that goes beyond basic SPF/DKIM/DMARC validation. It probes 11 layers of your email security stack — from DNS authentication and DKIM key strength to supply-chain attacks like Ghost-Sender, EchoSpoofing, and BreakSPF — and returns a composite score (0-100) with a clear verdict: SPOOFABLE or PROTECTED.
pip install dnspython
python spoofscore.py example.comThat's it. One dependency. No config files. No API keys.
| # | Layer | What | How |
|---|---|---|---|
| 1 | DNS Authentication | MX, SPF, DMARC, DKIM | Provider-aware DKIM with 80+ selectors + wildcard canary |
| 2 | SMTP/TLS Probing | STARTTLS, TLS version, cipher | Live connection to mail server on port 25 |
| 3 | Mail Platform | Email service provider | Fingerprint from MX hostname (Google, M365, SES, Zoho, ProtonMail, Mimecast) |
| 4 | DKIM Key Strength | Key type, bit length, revocation | RSA vs Ed25519, flags weak keys (<=1024-bit), detects revoked selectors |
| 5 | SPF Chain Analysis | Include tree walking, BreakSPF | RFC 7208 10-lookup limit, void lookups, dangling includes, multi-tenant shared infra, wide CIDR detection |
| 6 | Transport Security | MTA-STS, DANE/TLSA, BIMI, TLS-RPT, DNSSEC | Policy file validation, certificate checks (RFC 8461, RFC 7672) |
| 7 | Reputation | RBL/DNSBL scan | 40 major blocklist zones (Spamhaus, SpamCop, Barracuda, SORBS, UCEPROTECT, and more) |
| 8 | Infrastructure | FCrDNS, DMARC sp=, alignment | Forward-confirmed reverse DNS, subdomain policy mismatch, aspf/adkim analysis |
| 9 | Policy Analysis | pct, t=y, np=, deprecated tags | Detects DMARC testing mode, partial enforcement, and DMARCbis deprecated tags |
| 10 | Supply-Chain Risk | Ghost-Sender, EchoSpoofing | Gateway bypass via direct tenant delivery, Proofpoint relay abuse |
| 11 | Composite Score | Weighted 0-100, interaction penalties | Spoofability verdict + prioritized remediation with exact DNS records |
Score = Base Points + Penalties Grade Scale
┌─────────────────────────────┐ ┌───────────┐
│ DMARC p=reject +30 │ │ A 80-100 │
│ DMARC p=quarantine +15 │ │ B 60-79 │
│ DMARC p=none +5 │ │ C 40-59 │
│ SPF -all (hardfail) +20 │ │ D 20-39 │
│ SPF ~all (softfail) +15 │ │ F 0-19 │
│ DKIM present +15 │ └───────────┘
│ TLS 1.3 +15 │
│ TLS 1.2 +10 │ Max: 100
│ MTA-STS +10 │ Spoofable: < 60
│ DANE/TLSA +10 │ Protected: ≥ 60
└─────────────────────────────┘
All 15 penalties (interaction-aware deductions)
| Category | Issue | Pts |
|---|---|---|
| Critical | SPF +all (anyone can send as you) |
-10 |
| Critical | RBL blocklisted (active abuse) | -10 |
| High | Ghost-Sender gateway bypass | -5 |
| High | EchoSpoofing relay abuse | -5 |
| High | SPF exceeds 10-lookup limit | -5 |
| High | DMARC sp= subdomain mismatch |
-5 |
| High | DMARC pct < 100 (partial enforcement) |
-5 |
| High | DMARC t=y testing mode |
-5 |
| Medium | Relaxed SPF+DKIM alignment | -3 |
| Medium | Multiple SPF records | -3 |
| Medium | Multiple DMARC records | -3 |
| Medium | Weak DKIM key (<=1024-bit) | -3 |
| Medium | SPF void lookups > 2 | -3 |
| Low | SPF ptr mechanism (deprecated) |
-2 |
| Low | SPF wide CIDR (<=/20) | -2 |
Important
SpoofScore is not just another DMARC checker. Most tools validate DNS records. SpoofScore tells you if those records actually prevent spoofing, and what to fix if they don't.
| Capability | SpoofScore | Spoofy | espoofer | checkdmarc | mailvalidator | dnsarmor |
|---|---|---|---|---|---|---|
| Primary question | Spoofable? | Spoofable? | Bypass auth? | Valid record? | Security grade? | DNS secure? |
| Composite 0-100 score | ✅ | ❌ | ❌ | ❌ | Penalty | Finding |
| 11-layer analysis | ✅ | ❌ | ❌ | ❌ | Partial | DNS only |
| Spoofability verdict | ✅ | ✅ | N/A | ❌ | ❌ | ❌ |
| Wildcard DKIM canary | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Provider-aware DKIM | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| DKIM key strength audit | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| DKIM selectors | 80+ | API | N/A | 0 | 0 | Built-in |
| BreakSPF detection | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| SPF multi-tenant analysis | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| SPF dangling includes | ✅ | ❌ | ❌ | ❌ | Void only | ❌ |
| SPF void lookup limit | ✅ | ❌ | ❌ | ✅ | ✅ | ❌ |
DMARC sp= mismatch |
✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| DMARC alignment analysis | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| DMARC pct/t=y/np= parsing | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Ghost-Sender detection | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| EchoSpoofing detection | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| RBL/DNSBL zones | 40 | 0 | 0 | 0 | 104 | 13 |
| FCrDNS | ✅ | ❌ | ❌ | ✅ | Partial | ❌ |
| MTA-STS policy validation | ✅ | ❌ | ❌ | ✅ | ✅ | ✅ |
| DANE/TLSA + DNSSEC | ✅ | ❌ | ❌ | ✅ | ✅ | ✅ |
| BIMI + TLS-RPT | ✅ | ❌ | ❌ | ✅ | ✅ | ✅ |
| Remediation w/ DNS records | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ |
| Interaction-aware scoring | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Batch CSV for research | ✅ | ✅ | ❌ | ✅ | ❌ | ✅ |
| Dependencies | 1 | 2 | 5+ | 7 | 6+ | 3 |
Note
Where others beat us (for now):
mailvalidator checks 104 RBL zones (we check 40), and dnsarmor does DNSSEC chain validation.
We focus on the question that matters most to red teams and defenders: can this domain be spoofed?
python spoofscore.py example.compython spoofscore.py example.com another.org third.govpython spoofscore.py -f domains.txtpython spoofscore.py -f domains.txt -o results.csvpython spoofscore.py example.com --jsonpython spoofscore.py -f 1000-domains.txt -o scan.csv --smtp-threads 30All CLI options
| Flag | Description | Default |
|---|---|---|
domains |
One or more domains to scan | |
-f, --file |
File with one domain per line | |
-o, --output |
Output CSV file path | |
--json |
Output JSON instead of CLI report | false |
--smtp-threads |
SMTP probing threads for batch mode | 10 |
--version |
Print version and exit |
CSV columns (for research/batch scanning)
| Column | Description |
|---|---|
domain |
Target domain |
score |
Composite score 0-100 |
grade |
Letter grade A-F |
spoofable |
Yes/No verdict |
has_mx |
MX record exists |
mx_primary |
Primary MX hostname |
spf_mechanism |
SPF all-mechanism (hardfail/softfail/neutral/permissive/missing) |
spf_record |
Raw SPF TXT record |
spf_multiple |
Multiple SPF records detected |
spf_has_ptr |
SPF uses deprecated ptr mechanism |
spf_wide_cidrs |
Wide CIDR ranges (<=/20) in SPF |
dmarc_policy |
DMARC p= value |
dmarc_record |
Raw DMARC TXT record |
dmarc_effective |
Effective DMARC policy (after pct/t=y) |
dmarc_aspf |
SPF alignment mode (strict/relaxed) |
dmarc_adkim |
DKIM alignment mode (strict/relaxed) |
dmarc_rua |
DMARC aggregate report URI |
dkim_found |
DKIM selector discovered |
dkim_selectors |
Found selector names |
dkim_key_info |
Key type and bit length |
dkim_weak |
Weak key detected (<=1024-bit) |
dkim_dangling |
Dangling DKIM CNAME (subdomain takeover risk) |
starttls |
STARTTLS support |
tls_version |
Negotiated TLS version |
tls_cipher |
Cipher suite |
platform |
Detected mail platform |
spf_lookups |
SPF DNS lookup count |
spf_void_lookups |
SPF void lookup count |
spf_exceeds_limit |
Exceeds 10-lookup limit |
spf_void_exceeds |
Exceeds void lookup limit |
spf_dangling |
NXDOMAIN includes |
spf_chain_depth |
Include tree depth |
spf_ip_count |
Total IP ranges in SPF tree |
spf_shared_includes |
Multi-tenant includes found |
spf_multi_tenant_list |
List of shared SPF includes |
mta_sts |
MTA-STS configured |
mta_sts_mode |
MTA-STS policy mode (enforce/testing/none) |
dane_tlsa |
DANE/TLSA present |
dnssec |
DNSSEC validation (AD flag) |
bimi |
BIMI record present |
tls_rpt |
TLS-RPT configured |
rbl_listed |
Blocklisted zones |
rbl_clean |
Clean on all RBL zones |
fcrdns_ptr |
PTR record |
fcrdns_verified |
Forward-confirmed |
sp_mismatch |
sp= policy mismatch |
dkim_wildcard |
Wildcard _domainkey detected |
routing_risk |
Ghost-Sender routing risk |
routing_eol_endpoint |
Direct Exchange Online endpoint |
echospoof_risk |
EchoSpoofing relay risk |
laundromarc_risk |
LaunDroMARC report risk |
JSON output (single domain)
{
"domain": "example.com",
"score": 45,
"grade": "C",
"spoofable": "Yes",
"has_mx": "Yes",
"mx_primary": "mx1.example.com",
"spf_mechanism": "softfail",
"dmarc_policy": "none",
"dmarc_effective": "none",
"dmarc_aspf": "relaxed",
"dmarc_adkim": "relaxed",
"dkim_found": "Yes",
"dkim_selectors": ["selector1"],
"dkim_key_info": "RSA 2048-bit",
"platform": "Microsoft 365",
"mta_sts": "No",
"mta_sts_mode": "none",
"dane_tlsa": "No",
"dnssec": "No",
"rbl_clean": "Yes",
"routing_risk": "No",
"echospoof_risk": "No",
"remediation": [
{
"priority": "CRITICAL",
"issue": "DMARC policy is 'none' (monitor only)",
"fix": "Upgrade to p=reject to block spoofed mail",
"record": "v=DMARC1; p=reject; rua=mailto:dmarc@example.com"
}
]
}SpoofScore was built for and validated in academic research. We scanned 900 government domains across 10 ASEAN nations and 4 comparative countries as part of a study presented at IDSECCONF 2026.
Key findings from the scan:
- 367 out of 900 government domains (40.8%) are spoofable
- Average email security score: 37.9/100 (Grade D)
- Zero domains achieved Grade A
- 97 domains vulnerable to Ghost-Sender gateway bypass
- 520 domains share multi-tenant SPF infrastructure (BreakSPF exposure)
If you use SpoofScore in your research, please cite us:
@software{spoofscore,
author = {Ahmad Al Harrizuan Bin Izadin},
title = {SpoofScore: 11-Layer Email Security Scanner},
version = {3.0.0},
url = {https://github.com/harrizuan/spoofscore},
year = {2026}
}Tip
Run SpoofScore from a VPS with port 25 open for full Layer 2 (SMTP/TLS) results. Most ISPs and cloud providers block outbound port 25 on home connections.
- Python 3.8+ required. Only one dependency:
dnspython - DKIM probes 80+ selectors covering all major providers. Custom selectors may still be missed
- RBL checks query 40 major blocklist zones. Some zones may rate-limit
- Layer 10 checks for Ghost-Sender and EchoSpoofing supply-chain risks
- This is a point-in-time scan. DNS records and mail server configs change
pip install dnspythonMIT. Use it, fork it, build on it.
Built by bau1u. One dependency. Eleven layers. One answer.
Can someone impersonate your domain?
Find out in seconds.
