Split from #106.
Behavior
When OpenDKIM cannot determine a message's sender (no From: header, or a From: that cannot be parsed), the code logs:
opendkim[...]: <jobid>: can't determine message sender; accepting
...and unconditionally returns SMFIS_ACCEPT. This happens regardless of any On-BadSignature, On-NoSignature, or related policy configuration.
The code path in mlfi_eom() that handles mctx_headeronly = TRUE (set when sender determination fails) ends with a hardcoded return SMFIS_ACCEPT (after inserting an AR header with dkim=permerror), bypassing all handler dispatch logic.
Why it matters
A message with no From: header is malformed per RFC 5322 and carries no DKIM signature. In a strict policy environment (On-BadSignature reject, RequiredHeaders yes, etc.) the expectation is that such messages are rejected, not silently accepted.
This also has a defense-in-depth relationship to SMTP smuggling (e.g. CVE-2023-51764, the Postfix bare-newline issue fixed in December 2023): a smuggled message injected via a bare-LF end-of-data sequence typically arrives with no headers at all, hitting exactly this code path. Modern Postfix with smtpd_forbid_bare_newline = yes blocks the injection before it reaches OpenDKIM, but older deployments or other MTAs may not — and OpenDKIM should arguably provide defense-in-depth rather than always accepting.
Suggested fix
When mctx_headeronly is set and the status is DKIMF_STATUS_BADFORMAT, dispatch through the existing On-BadSignature handler rather than returning SMFIS_ACCEPT directly. Alternatively, a dedicated On-NoSender handler could be added for finer-grained control.
cc @mskucherawy — curious whether the "always accept" behavior here was deliberate (e.g. to avoid disrupting legitimate mail from broken clients) or an oversight.
Split from #106.
Behavior
When OpenDKIM cannot determine a message's sender (no
From:header, or aFrom:that cannot be parsed), the code logs:...and unconditionally returns
SMFIS_ACCEPT. This happens regardless of anyOn-BadSignature,On-NoSignature, or related policy configuration.The code path in
mlfi_eom()that handlesmctx_headeronly = TRUE(set when sender determination fails) ends with a hardcodedreturn SMFIS_ACCEPT(after inserting an AR header withdkim=permerror), bypassing all handler dispatch logic.Why it matters
A message with no
From:header is malformed per RFC 5322 and carries no DKIM signature. In a strict policy environment (On-BadSignature reject,RequiredHeaders yes, etc.) the expectation is that such messages are rejected, not silently accepted.This also has a defense-in-depth relationship to SMTP smuggling (e.g. CVE-2023-51764, the Postfix bare-newline issue fixed in December 2023): a smuggled message injected via a bare-LF end-of-data sequence typically arrives with no headers at all, hitting exactly this code path. Modern Postfix with
smtpd_forbid_bare_newline = yesblocks the injection before it reaches OpenDKIM, but older deployments or other MTAs may not — and OpenDKIM should arguably provide defense-in-depth rather than always accepting.Suggested fix
When
mctx_headeronlyis set and the status isDKIMF_STATUS_BADFORMAT, dispatch through the existingOn-BadSignaturehandler rather than returningSMFIS_ACCEPTdirectly. Alternatively, a dedicatedOn-NoSenderhandler could be added for finer-grained control.cc @mskucherawy — curious whether the "always accept" behavior here was deliberate (e.g. to avoid disrupting legitimate mail from broken clients) or an oversight.