-
v0.45.0 Stable
released this
2026-08-25 15:41:16 -05:00 | 72 commits to main since this releaseMail that arrives through a forwarder is now judged by who actually sent it.
56% of the sampled inbox is relayed, and every check that reads the sending
domain was reading the forwarder. Also fixes a DKIM property name that had the
RFC 8058 coverage check inert on the whole Gmail tenant.Added
-
mail/origin.py— recovers the original sender from behind a forwarding
hop, shared by both tenants.Origincarries the domain to judge, a
provenance (direct/relayed/relayed_unresolved), the relay, and
whether the answer is a claim.The design this replaces read the ARC chain, and it could not have worked.
RFC 8617 puts the first relay's record of the original sender's
authentication in thei=1ARC-Authentication-Results. On all 228 relayed
messages sampled, that header reads in full:i=1; mail.protonmail.ch— an
authserv-id and nothing else. The chain validates and carries no verdicts
inside it. A resolver written against it returns "the original failed
authentication" for every forwarded message, and since that is a blocking
signal it would have refused 28 of 28 relayed unsubscribe offers where 21 are
allowed today. Measured before the module was written.What is available is the rewritten
From— shaped"Example Store - hello at store.example" <hello_at_store_example_TOKEN@RELAY>— carried in the display
half on 228 of 228 and the local part on 117. Reading it is the same
trust decision as trusting the relay's ARC seal: same domain, same key, same
notary. It is not read without the relay's own verified DKIM signature over
From, present on 232 of 232 signatures sampled.The downgrade is coverage, not trust, and it bounds the feature. The chain
would have carried a verdict; the rewrittenFromcarries a claim. So
Origin.claimedis always true on relayed mail, the output says so in a
sentence, and the unsubscribe gate was deliberately not retiered on
"authenticated origin" — that question has no input on this account.TRUSTED_RELAYSissimplelogin.coandduck.com, both from observation.
A third was expected and appears on zero of 400 messages, so it is not there. -
origininget_message_securityon both tenants, always present so the
shape does not change between direct and relayed mail. The chained-relay case
is live and handled:privacy.example → simplelogin.co → duck.comreports
the origin, not the previous hop, because a candidate that is itself a relay
is a hop rather than a sender.
Fixed
-
The RFC 8058 signature-coverage check was inert on the entire Gmail
tenant.MethodResult.domainlooked forheader.d; Gmail reports the DKIM
domain asheader.iand never asheader.d— 492 of 492 verdicts
sampled. So the property returned""for every DKIM verdict there, which
meantunsubscribe._verified_signaturesfound nothing,headers_are_signed
returnedNonerather than a verdict, and all 48 one-click offers were
reported assignature_coverage_unknowninstead of being checked. The
security report also showed a DKIM pass with no signing domain.Fixing it turns one message from allowed into correctly refused: a sender
whose signature coversList-Unsubscribebut notList-Unsubscribe-Post,
which RFC 8058 §3.2 requires for one-click. -
brand_mismatchjudges the recovered origin. Seven relayed Facebook
messages were refused for impersonating Facebook — they came from
facebookmail.comthrough SimpleLogin, and the check sawsimplelogin.co.
Relayed unsubscribe offers go from 21 allowed / 7 refused to 28 / 0 on the
sample, with no direct-mail decision changed._reply_to_mismatchis deliberately left alone: under relaying bothFrom
andReply-Toare the relay, so it compares a domain against itself and is
silent rather than wrong — and it is non-blocking, so a misfire costs a
warning.
Changed
authresults.summarisenames the relay and refuses to lend it the sender's
credibility. Untreated it reported "the message really was sent by
'simplelogin.co'" — true and useless — beside a DMARC policy note describing
the relay's published policy as though it were the sender's. That is
false reassurance rather than a false alarm: a brand mismatch is visible when
it misfires, a strong policy attributed to the wrong domain is not.
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
-