Invalid ARC signatures due to wrong body hashes
The ARC signature produced by arc_sign.py
contains a wrong body hash value. This results in failed ARC checks at the final recipient. That likely leads to tagging Mailman sent messages as spam.
The reason is that the sign()
method in arc_sign.py
is called with the original email body before adding the footer template content. This essentially results in sign()
(or rather authheaders.sign_message()
) computing the same body hash value as in the original DKIM header.
So what happens is:
-
authheaders.sign_message()
computes the body hash over the original, unaltered email body -
sign()
adds the headersARC-Authentication-Results
,ARC-Message-Signature
andARC-Seal
to the message - Somewhere along Mailman's pipelines and switchboards the template footer is appended to the email body
- The message is sent and delivered to the recipient
- The recipient calculates the hash for new body which is "original mail body + footer" and compares it against the
bh
attribute in theARC-Message-Signature
header. Butbh
contains only the hash over "original mail body". The comparison must fail.
I could verify and reproduce that:
- The
bh
-value in the Mailman createdARC-Message-Signature
header is identical to thebh
-value in the originalDKIM
-header. This cannot be correct since the email body gets modified by Mailman by adding the footer. - The
sig
parameter provided toarc_sign.py
'ssign()
contains just the original mail text without footer. I've added debug outputs to thesign()
method to check that.
Additionally, I found a comment in pipelines/builtin.py
saying "All decoration is now done in delivery." which I read as an indicator that headers, footers etc. are added to the email immediately before delivery and after ARC processing.
I could think of two possible solutions:
- Push ARC signing further down the processing queue, after footers etc. have been added to the body; or
- Add an
l
attribute to theARC-Message-Signature
header indicating up to which byte position in the body the hash shall be computed. This would be the length of the original body, without Mailman footers.
I'm using a fresh install of version 3.3.4 without any customizations.