In brief. headercheck reads raw email headers and reports the things that give a phishing message away: SPF/DKIM/DMARC results, mismatches between the From, Reply-To, and Return-Path domains, display-name spoofing, lookalike and homoglyph sender domains, and the relay-hop timeline. It runs entirely offline — no network, no API keys, standard library only.
The problem
When someone forwards you a suspicious email, the headers hold most of the answer — but reading them by eye is tedious and easy to get wrong. The authentication results are buried in a long Authentication-Results line, the real sending domain may not match the friendly name, and the clues are scattered across fields that were never meant for humans to scan quickly.
How it works
You hand it an .eml file or paste the raw headers, and it parses out the sender fields, the authentication results, and the Received chain, then runs a set of checks:
- Authentication — SPF, DKIM, and DMARC, parsed from the headers the receiving server stamped on.
- Address mismatches — the From, Reply-To, and Return-Path registrable domains. A Reply-To pointing somewhere other than the From domain is a classic redirect tell.
- Display-name spoofing — a brand name or a different email address sitting in the display name while the real sending domain is something else.
- Lookalike domains — senders imitating a known brand through character swaps, homoglyphs, or punycode (
micros0ft-support.com,paypa1.ru,xn--domains). - Relay timeline — the
Receivedhops oldest to newest, with per-hop delays and originating IPs.
Using it
# an .eml file or a text file of raw headers
python headercheck.py message.eml
# paste headers from the clipboard (macOS)
pbpaste | python headercheck.py
To get the raw headers out of your client: Gmail's "Show original", Outlook's message Properties → Internet headers, or Apple Mail's View → Message → Raw Source.
A note on trust
Headers can be forged, and only the hops added by servers you trust are themselves trustworthy. The tool is a triage aid: it surfaces the signals quickly and in one place, but a confident attacker can make some of them look clean. Treat a green result as the absence of easy tells, not proof of safety.