« Phase 10

Lab 01 — Email Authentication Analyzer

Operation Cedar Lattice, Phase 10.

Parse email header authentication fields and compute a structured phishing-risk score. This lab implements the detection logic that a SOC analyst or email security platform would apply to every inbound message: evaluate SPF, DKIM, and DMARC results; check domain alignment; flag reply-to anomalies; produce a weighted risk score and risk level.

Safety. This lab is an analyzer over synthetic header dictionaries. There is no email-sending code, no SMTP connection, no credential harvesting, and no working phishing tool. The input is a Python dict; the output is a risk score and findings list.


What You Will Build

Five functions that together implement a phishing risk analysis pipeline:

FunctionInputOutput
spf_analysis(header)header dict{pass, finding}
dkim_analysis(header)header dict{pass, finding, domain_match}
dmarc_analysis(header)header dict{enforced, policy, finding}
phish_risk_score(header)header dictinteger (0-15+)
analyze(header)header dict{risk_score, risk_level, findings}

Header Dict Schema

header = {
    "from_domain":    str,   # domain in From: header (e.g., "example.com")
    "spf_result":     str,   # 'pass'|'fail'|'softfail'|'neutral'|'none'|'permerror'|'temperror'
    "dkim_result":    str,   # 'pass'|'fail'|'neutral'|'none'|'permerror'|'temperror'
    "dkim_domain":    str,   # d= tag value from DKIM-Signature header (may be empty)
    "dmarc_policy":   str,   # 'none'|'quarantine'|'reject'
    "dmarc_result":   str,   # 'pass'|'fail'
    "reply_to_domain": str,  # domain from Reply-To: header (empty string if not present)
}

Risk Score Weights

ConditionPoints
SPF fail/softfail/none/permerror/temperror+3
DKIM not pass+3
DMARC policy is none or missing+2
DKIM passes but dkim_domain base differs from from_domain base+4
reply_to_domain non-empty and base differs from from_domain base+3

Risk levels:

  • LOW: 0–3
  • MEDIUM: 4–6
  • HIGH: 7–10
  • CRITICAL: 11+

Domain base extraction: last two dot-separated parts. mail.example.comexample.com.


Files

FilePurpose
lab.pyYour implementation — stubs with NotImplementedError
solution.pyComplete reference solution
test_lab.py13 pytest tests
requirements.txtpytest>=7.0

Running the Tests

# Run against your implementation (should fail with NotImplementedError)
pytest -q

# Run against reference solution (all 13 should pass)
LAB_MODULE=solution pytest -q

Learning Objectives

After completing this lab you should be able to:

  1. Explain the difference between SPF fail and softfail and why both add risk.
  2. Implement relaxed DMARC domain alignment (organizational domain comparison).
  3. Describe why reply-to mismatch is a high-confidence phishing signal.
  4. Compute a weighted phishing risk score from raw header fields and map it to a risk level.
  5. Enumerate findings from multiple sub-analyses into a unified result.

« Phase 10 README | Lab 02 — OSINT Surface Mapper