Tools · Email security · 10 / 18
Reading raw email headers: tracing the Received chain hop by hop
Open the raw source of a message, read Received headers from bottom to top, identify the true originating server, and know which headers a sender can forge.
Getting the raw source
Every client can show the original message: “Show original” in Gmail, “View message source” in Outlook on the web, and “View Source” in Thunderbird. Save it as a .eml file so you analyze an unmodified copy and keep it as evidence.
Reading Received headers
Each server that handles a message adds a Received header at the top, so the newest is first and the oldest is last. Read from the bottom up. The most trustworthy hop is the first one added by your own organization’s servers, because it records the IP that actually connected to you. Anything below that line was written by systems you do not control and may be forged.
Received: from mx.example.org (10.0.0.5) by mbx01.example.org; Mon, 2 Nov 2026 10:02:11 +0000 Received: from mail-out.sender.example (198.51.100.40) by mx.example.org with ESMTPS; Mon, 2 Nov 2026 10:02:10 +0000 Received: from [192.0.2.17] (unknown) by mail-out.sender.example; Mon, 2 Nov 2026 10:02:08 +0000 <- written by the sender's side
Lab: trace a message you received
Save the raw source of a legitimate external message. Extract only the Received lines, number them from the bottom, and for each record the from host, by host, IP, and timestamp. Mark the first hop added by your provider and note the connecting IP there. Compare time gaps between hops; large gaps can indicate queueing or a header inserted out of order.
grep -n '^Received:' -A2 message.eml
python3 - <<'EOF'
import email
m = email.message_from_file(open('message.eml'))
for i, h in enumerate(reversed(m.get_all('Received', [])), 1):
print(i, ' '.join(h.split())[:160])
EOFWhat can be forged
From, Reply-To, Date, Message-ID, and any Received lines added before the message reached your servers are written by the sender and can be anything. Authentication-Results added by your own provider, and the connecting IP in your first trusted hop, are the reliable anchors.
- Forgeable: From, Reply-To, Date, Message-ID, early Received lines
- Reliable: your provider’s Received line and Authentication-Results
Diagram
Reading Received headers
- Bottom
Oldest hop; written by the sender side and untrusted.
- Middle
Relays and the sender’s outbound gateway.
- Trusted boundary
First hop added by your own servers; records the real connecting IP.
- Top
Internal delivery to the mailbox.
Check yourself
1. Where is the newest Received header?
2. Which Received line gives the most reliable connecting IP?
3. Which header can the sender set to any value?