Skip to content

SPF passed, and the message is still forged

"SPF check passed" does not mean the message is genuine. It means the sending server was authorised for its own domain — an entirely different claim.

Email security
/
2026-04-09
/
5 min read

The checks look at different domains

A message carries two sender addresses, not one. The first is the envelope address — the return path given during the SMTP session. The second is the `From:` header, the address the user sees on screen.

SPF checks the first. So if an attacker puts their own domain in the envelope and yours in `From:`, SPF passes, because it never looks at `From:` at all.

That is why "SPF passed" does not rule out forgery. What ties the two addresses together has its own name: alignment.

What alignment is

DMARC takes the result of the two checks and adds one condition on top: does the domain that was checked match the domain in `From:`?

For SPF, the envelope domain is compared with the `From:` domain. For DKIM, the signing domain is compared with the `From:` domain. One of the two matching is enough.

So the right question is not "did SPF pass" but "did it align". A report that does not answer the second question is useless.

Figure 1SPF checks the envelope domain, not `From:`. For a message to count as genuine, the check has to pass and the checked domain has to match `From:`.

Why DKIM is the sturdier of the two

SPF is bound to the route: it looks at which server delivered the message. So forwarding — through a mailing list, say — breaks SPF, because the last hop is a different server.

DKIM is bound to the message: the signature covers headers and part of the body, and it travels with the message. Forwarding preserves it as long as the content is not modified.

In practice both are deployed. But if one has to come first, DKIM delivers more value and breaks less.

Policy is tightened in stages

A DMARC policy takes one of three values: `none` — do nothing, just send reports; `quarantine` — put suspect mail in spam; `reject` — refuse it.

The right path starts at `none`. Nothing changes at that stage, but reports start arriving and you learn who sends mail as your domain. The list is nearly always longer than expected.

Then `quarantine`, and only then `reject`. Weeks should pass between the stages, because a system that sends once a month will not appear in the first week.

Who reads the reports

DMARC reports arrive as XML and are not human-readable. So the `rua` address is frequently pointed at a mailbox nobody opens.

Skipping that stage is what makes the move to `reject` dangerous: the reports are exactly what tells you whether it is safe. They list, per source, how many messages passed and how many failed alignment.

A practical note: look at a full month of reports before moving to `reject`. Monthly statements, payroll systems and annual notices are found on precisely that interval.

Figure 2Policy is tightened in stages. The `none` stage changes nothing, and it is exactly the stage that shows who sends mail in your name.

Third-party senders

Most of the trouble comes not from your own server but from others: the marketing platform, the accounting system, the CRM, the monitoring service — all of them send mail as your domain.

Each has two options: let them sign for your domain with a DKIM key, or give them a dedicated subdomain. The second is considerably cleaner: if `mail.example.uz` fails, the main domain is untouched.

The SPF record has a limit of its own: no more than ten DNS lookups. Every new service brings you closer to it, and once exceeded SPF stops working altogether.

The attack DMARC does not stop

DMARC protects your domain only. It does nothing about a message whose `From:` carries an entirely different domain.

So the most common attack is built differently: the display name reads "Accounts Payable" while the address is unfamiliar. Many mobile mail clients show only the name.

The other variant is a lookalike domain, one letter swapped or inserted. That domain has its own correct SPF and DKIM and passes every check there is.

Figure 3The chain of checks ends at the `From:` header. The name a user actually sees is checked by no standard at all — which is where the attack lives.

Inventory the domains

So the work starts by listing domains. Every domain that sends mail on behalf of the company goes on the list — and so does every domain that does not.

The non-sending ones matter separately: they get an empty SPF record and a `reject` policy. Otherwise they remain a ready-made instrument for an attacker.

And watching for lookalikes joins the list. A freshly registered similar name usually appears weeks before the attack does, which is time you can use.

All posts

Shall we talk?

Show us a domain and we will give you a first read on your current external posture. Nothing is changed at this stage.

Let’s start
Get in touch
Get in touch