CertaDNS
Skip to lesson

What a Signature Covers · lesson 3 of 3

Choosing what to sign

After this lesson you can

Pick an h= list that resists tampering without making the signature needlessly brittle.

Assumes you have read DKIM-Signature, tag by tag.

h= is a trade. Every header you sign is a header nobody can tamper with, and a header whose alteration by a legitimate intermediary breaks your signature. Signing everything is as wrong as signing nothing.

The ones that must be signed

  • From. Non-negotiable, and From is the only header required by the specification. An unsigned From would let anyone change the displayed sender on a validly signed message, which is exactly the attack DKIM exists to stop.
  • Subject. The other field the reader acts on. Leaving it unsigned allows a signed message to be re-titled.
  • To, Date, Message-ID. Cheap, stable, and they make replay and re-addressing visible.

The ones to leave out

  • Received. Added by every hop. Signing it guarantees failure at the second one.
  • Return-Path. Rewritten by the receiving server.
  • List-*. If your mail ever reaches a mailing list, the list adds these. Signing them pre-emptively is a way of failing on lists.
  • DKIM-Signature. Handled by the specification, not by you.

Oversigning

Listing a header name in h= more times than it appears in the message signs its absence as well as its value. It is the standard defence against a header being added rather than changed.

h=from:from:to:subject:date:message-id

  "From appears once in this message, and if a second
   From header shows up, this signature fails."

Without it, an attacker can prepend a second From header to a signed message. The signature still verifies against the original one, while many clients display the new one. Oversigning From and Subject closes that, costs nothing, and is what most modern signers do by default.

A reasonable default

h=from:from:to:subject:subject:date:message-id:mime-version:content-type — the fields a reader acts on, with the two most abusable oversigned, and nothing an intermediary routinely rewrites. If your signing platform does not let you set this, its own default is usually close enough; check it once rather than assuming.

Knowledge check

A signed message arrives with two From headers. The signature verifies, and the client displays the attacker’s address. What was wrong with h=?

Try it on a real domain

Free, no account, public DNS only.

Last reviewed