Question

I am very successfully using PHPMailer to send out SPF/DKIM emails from my website. Successfully as in its spam-rating has gone to practically zero.

However, I would like to add a custom mail header to the signature as to have some authenticity of its value.

  1. Can this be done?
  2. Can this be done with PHPMailer?
  3. If yes: how?

Illustration:

Let's say I have a custom field X-app-originalSender.

When I look at the source of an outgoing email message, I see

Delivered-To: example@internet.com
Received: by 10.10.10.10 with SMTP id v7csp230623wjf;
        Tue, 6 May 2014 05:20:04 -0700 (PDT)
X-Received: by 10.10.10.10 with SMTP id v2mr38890846oer.37.1399378803091;
        Tue, 06 May 2014 05:20:03 -0700 (PDT)
Return-Path: <mister+caf_=example=internet.com@example.com>
Received: from mail-oa0-x22e.gogol.com (mail-oa0-x22e.gogol.com [2607:f8b0:4003:c02::22e])
        by mx.gogol.com with ESMTPS id vj5si8402166obb.10.10.10.10.05.20.02
        for <example@internet.com>
        (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128);
        Tue, 06 May 2014 05:20:03 -0700 (PDT)
Received-SPF: none (gogol.com: mister+caf_=example=internet.com@example.com does not designate permitted sender hosts) client-ip=2607:f8b0:4003:c02::22e;
Authentication-Results: mx.gogol.com;
       spf=neutral (gogol.com: mister+caf_=example=internet.com@example.com does not designate permitted sender hosts) smtp.mail=mister+caf_=example=internet.com@example.com;
       dkim=pass header.i=@website.com
Received: by mail-oa0-x22e.gogol.com with SMTP id i4so9294020oah.19
        for <example@internet.com>; Tue, 06 May 2014 05:20:02 -0700 (PDT)
X-gogol-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=x-gm-message-state:delivered-to:to:subject:dkim-signature:date:from
         :reply-to:message-id:mime-version:content-type;
        bh=ObNkr4SNFALRke4Aa0VT3bZmEq19ZIWHnngz5uCPG3U=;
        b=hbiSE6cEr+FEAIGUCqsCfNOQq9SYsYZ9fa4lC333uWyUY9x6srMgwHeOa28IoKxD31
         76LnRKfqc3YZBqMFKJ37plvyVXdaRsPCwLdYrNNMxmvNVVb5siC8r6Frx6v2QCBPcPEQ
         U+c6Qn/Rl9dHYHD9GCoC346DWkC8CcAF/MG6oipVcf9kojwfuYR/UgzpjmVMKcueUpEy
         nHKKGmfVT9RcqHgPMsOj1/W8/k/drKRUk2QlzLH8anR6foeWqjNtyUmHYxo/Qc6eKoxh
         Zua23/rTAgb/1SF4yalyeaeTa9xWO07bHeDwgknvg7QuYBSjDt+7iIXngkZXVYaSNAEJ
         xZIw==
X-Gm-Message-State: ALoCoQmfamLXlJ4EXccj5awNP/G2qU/uIZcjuLJKrB+5YOVHQsc1ARYlMw6wxCDTCchbQnufkN4N
X-Received: by 10.10.10.10 with SMTP id my9mr1885484obb.61.1399378802595;
        Tue, 06 May 2014 05:20:02 -0700 (PDT)
X-Forwarded-To: example@internet.com
X-Forwarded-For: mister@example.com example@internet.com
Delivered-To: mister@example.com
Received: by 10.10.10.10 with SMTP id hd5csp216265obb;
        Tue, 6 May 2014 05:20:01 -0700 (PDT)
X-Received: by 10.10.10.10 with SMTP id a49mr10690110eei.46.1399378800211;
        Tue, 06 May 2014 05:20:00 -0700 (PDT)
Return-Path: <server@website.com>
Received: from rembrandt.net.de (rembrandt.net.de. [10.10.10.10])
        by mx.gogol.com with ESMTPS id n46si13234148eeo.10.10.10.10.05.19.59
        for <mister@example.com>
        (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);
        Tue, 06 May 2014 05:20:00 -0700 (PDT)
Received-SPF: pass (gogol.com: domain of server@website.com designates 10.10.10.10 as permitted sender) client-ip=10.10.10.10;
Received: (qmail 29290 invoked by uid 10269); 6 May 2014 14:19:59 +0200
To: mister@example.com
Subject: Whatever
X-app-originalSender: Roger Rabbit
X-PHP-Originating-Script: 10269:class.phpmailer.php
DKIM-Signature: v=1; a=rsa-sha1; q=dns/txt; l=937; s=website;
  t=1399378799; c=relaxed/simple;
  h=From:To:Subject;
  d=website.com;
  z=From:=20"website.com=20Warning"=20<server@website.com>
  |To:=20mister@example.com
  |Subject:=20Whatever;
  bh=Yvxg9fVS37EmFVuVWzUji3Wry5Q=;
  b=JmNeGJsvhhC5s/rTLfXPSBte2NfYCPLNiNrNi4/bbjcdKvPNt/LvySGOpD+4hIAxsjwGtknsz7CMDOhcmJLPK/FHge18q+Dw1j0chtRehIZUdEHKcHDU5n2X2/x+ja+EohtfNFwCfjm3Zyfjf+cDyvsKUrf8l6mtWqK9oWpjyrg=
Date: Tue, 6 May 2014 14:19:59 +0200
From: "website.com Warning" <server@website.com>
Reply-To: "website.com Warnung" <server@website.com>
Message-ID: <59052014140619-L73ESg5cau@website.com>
X-Priority: 3
X-Mailer: website.com platform (https://website.com)
MIME-Version: 1.0
Content-Type: multipart/alternative;

I am most intrigued by the line h=From:To:Subject; and am assuming there must be a way to add my custom field to it.

How?

DKIM Specs

from http://dkim.org/specs/draft-allman-dkim-base-01.html#rfc.section.3.5

Signed header fields (plain-text, but see description; REQUIRED). A colon-separated list > of header field names that identify the header fields presented to the signing algorithm. The field MUST contain the complete list of header fields in the order presented to the signing algorithm. The field MAY contain names of header fields that do not exist when signed; nonexistent header fields do not contribute to the signature computation (that is, they are treated as the null input, including the header field name, the separating colon, the header field value, and any CRLF terminator), and when verified non-existent header fields MUST be treated in the same way. The field MUST NOT include the DKIM-Signature header field that is being created or verified. Folding white space (FWS) MAY be included on either side of the colon separator. Header field names MUST be compared against actual header field names in a case insensitive manner. ABNF: sig-h-tag = "h=" FWS hdr-name 0( *FWS ":" *FWS hdr-name ) hdr-name = field-name INFORMATIVE EXPLANATION: By "signing" header fields that do not actually exist, a signer can prevent insertion of those header fields before verification. However, since a sender cannot possibly know what header fields might be created in the future, and that some MUAs might present header fields that are embedded inside a message (e.g., as a message/rfc822 content type), the security of this solution is not total. INFORMATIVE EXPLANATION: The exclusion of the header field name and colon as well as the header field value for non-existent header fields prevents an attacker from inserting an actual header field with a null value.

Was it helpful?

Solution

You are right that it's possible to include arbitrary headers in a DKIM signature, but PHPMailer does not provide a means of doing that. The DKIM_Add method is where the interesting bit happens, and you can see in there that h=From:To:Subject; is hard-coded. Probably the easiest way around this is to subclass PHPMailer and rewrite this function to include your extra headers.

Update: PHPMailer now has support for adding extra headers into the DKIM signature via the DKIM_extraHeaders property, for example:

$mail->DKIM_extraHeaders = ['List-Unsubscribe', 'List-Help'];
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top