fix: trust an invitation that passed dmarc even when a forwarder broke its first signature

This commit is contained in:
Linus Rath
2026-10-29 04:50:15 +01:00
parent 47f2971899
commit 6133bcd951
2 changed files with 21 additions and 0 deletions
@@ -197,6 +197,23 @@ describe('getInvitationTrustAssessment', () => {
.toBe('trusted');
});
// A mailing list or a forwarder that rewrote the message broke the first
// signature; the sender's own one passed, and so did DMARC.
it('trusts a DMARC pass of the receiving server over a broken signature listed first', () => {
expect(getInvitationTrustAssessment(request, forged(
'dkim=fail header.d=lists.example.net header.s=l1; dkim=pass header.d=example.com header.s=k1; spf=softfail smtp.mailfrom=lists.example.net; dmarc=pass header.from=example.com',
), 'request')).toMatchObject({ level: 'trusted', reason: null });
// A pass only a lower header claims is the sender's word, not the server's.
const below = email({
from: [{ email: 'alice@example.com' }],
headers: [
{ name: 'Authentication-Results', value: 'mx.example.org; dkim=fail header.d=example.com; dmarc=fail header.from=example.com' },
{ name: 'Authentication-Results', value: 'relay.example; dmarc=pass header.from=example.com' },
],
});
expect(getInvitationTrustAssessment(request, below, 'request').reason).toBe('authentication_failed');
});
it('warns about a forged organizer whose mail passes only for the forger\'s domain', () => {
const e = email({
from: [{ email: 'mallory@forger.example' }],
+4
View File
@@ -483,6 +483,10 @@ export function hasAlignedAuthenticationPass(
}
function hasAuthenticationFailure(auth?: AuthenticationResults | null): boolean {
// DMARC passed on the receiving server's own header: one aligned method
// passed, and that is the verdict. A mailing list's or a forwarder's
// signature that broke on the way, listed first, flagged such a message.
if (auth?.dmarc?.result === 'pass') return false;
return Boolean(
auth?.dmarc?.result === 'fail'
|| auth?.dkim?.result === 'fail'