In email messages, DKIM signatures appear in a DKIM-Signature header, which lists a bunch of parameters:
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed; d=list.zfsonlinux.org; h=from:to:subject:message-id:in-reply-to:references:date [….]
The ‘h=’ list (which isn’t complete here) is a list of headers that have been signed. More specifically, it’s a list of instances of headers. If there are multiple instances of a given header in a message, DKIM defines an order to them and the instances of the header are checked (or used) in that order. So if you include ‘from’ once in the DKIM header list, you are saying that your DKIM signature includes DKIM‘s first ‘From:’ header in the message. If a second ‘From:’ header is added to the message, it’s not included what’s covered by your DKIM signature; it can have any value and the message will still pass DKIM validation.
As mentioned last time, including a header that doesn’t exist in the DKIM signature signs its absence; if that header is then added to the message, the DKIM signature will become invalid. DKIM signing things that aren’t there is sometimes called oversigninga header; you’re not just signing what’s present, you’re also signing what’s not. As a corollary of this, if you want to seal a message against having extra copies of some headers added, you can deliberately oversign existing headers. This is done by including their names an extra time in the h= list; the first time signs the existing header, and the second time signs that there’s no second header. So if we wanted to make sure no one added a second ‘From:’ to a message, we’d sign ‘h=from:from:[….]’.
Onereason to oversign existing headers that should only appear once is that anyone who adds a second ‘From:’, ‘Date:’ or whatever to your message is probably up to no good. Another reason is that it’s hard to predict which instance of the header a mail client will show to people reading the message, and there are probably some mail clients that will show the wrong instance of the header (the instance that isn’t covered by your DKIM signature and so can be set to anything by an attacker).
This creates several options and decisions:
do you make it so that certain headers can’t be added to the message later, like the List-* and Resent-* families, or allow them to be added later?
what headers do you sign if they’re present? For example, should you sign Resent-* or List-* headers at all?
do you oversign some existing headers so that no additional copies can be added?
Based on a quick skim of email that I have handy, relatively few sources of mail seem to be oversigningexisting headers. However, GMail does oversign at least some email for core headers like From: and Subject:. Since Google is one of the eight hundred pound gorillas of email, if they’re doing it people’s DKIM signature validation is at least prepared to cope with this.
(I suspect that having twoFrom:, Subject:, or so on headers trips enough spam detection systems that attackers don’t normally do it.)