Summary
A message can be crafted with a large number of DKIM-Signature headers, each referencing a distinct domain or a slow/non-responsive DNS name. OpenDKIM has no explicit cap on the number of signatures it will process, so each one triggers:
- A DNS lookup for the public key (potentially to an attacker-controlled or slow nameserver)
- A cryptographic verification operation
This is a meaningful amplification vector against any server running OpenDKIM in verify mode.
What protection exists today
MaximumHeaders (default 64KB) caps total header bytes, providing indirect protection. A typical DKIM-Signature header is roughly 400-600 bytes, so the default allows on the order of 100 or more signatures before the message is rejected.
DKIM_LIBFLAGS_VERIFYONE exists in libopendkim and would cause processing to stop after the first passing signature, but it is never set anywhere in opendkim itself.
What is missing
- No
MaximumSignatures (or equivalent) configuration option to cap the number of signatures processed per message.
DKIM_LIBFLAGS_VERIFYONE is not exposed or enabled by default, meaning opendkim always processes every signature even after finding a passing one.
Suggested fixes
- Add a
MaximumSignatures config option that rejects (or truncates processing of) messages with more than a configured number of DKIM-Signature headers, with a conservative default (e.g. 5-10).
- Consider enabling
DKIM_LIBFLAGS_VERIFYONE by default, or exposing it as a config option, so processing stops as soon as a passing signature is found.
- Consider adding a cap at the
libopendkim level so the protection is available to all library users, not just the opendkim milter.
Summary
A message can be crafted with a large number of
DKIM-Signatureheaders, each referencing a distinct domain or a slow/non-responsive DNS name. OpenDKIM has no explicit cap on the number of signatures it will process, so each one triggers:This is a meaningful amplification vector against any server running OpenDKIM in verify mode.
What protection exists today
MaximumHeaders(default 64KB) caps total header bytes, providing indirect protection. A typicalDKIM-Signatureheader is roughly 400-600 bytes, so the default allows on the order of 100 or more signatures before the message is rejected.DKIM_LIBFLAGS_VERIFYONEexists inlibopendkimand would cause processing to stop after the first passing signature, but it is never set anywhere in opendkim itself.What is missing
MaximumSignatures(or equivalent) configuration option to cap the number of signatures processed per message.DKIM_LIBFLAGS_VERIFYONEis not exposed or enabled by default, meaning opendkim always processes every signature even after finding a passing one.Suggested fixes
MaximumSignaturesconfig option that rejects (or truncates processing of) messages with more than a configured number ofDKIM-Signatureheaders, with a conservative default (e.g. 5-10).DKIM_LIBFLAGS_VERIFYONEby default, or exposing it as a config option, so processing stops as soon as a passing signature is found.libopendkimlevel so the protection is available to all library users, not just the opendkim milter.