Opened 13 years ago
Closed 3 months ago
#22837 closed defect (bug) (worksforme)
WP Needs to Set "Sender" and "Reply-To" or DKIM/DMARC will not work using wp-mail (via PHPMailer)
| Reported by: |
|
Owned by: | |
|---|---|---|---|
| Milestone: | Awaiting Review | Priority: | high |
| Severity: | major | Version: | 3.4.2 |
| Component: | Keywords: | close 2nd-opinion | |
| Focuses: | Cc: |
Description (last modified by )
I notice that for DKIM to function (while using DMARC) correctly for outgoing mail the PHPMailer object needs to make sure the Sender and Reply-To fields match the "From" field otherwise the "Return-Path" header uses the server it is sending from causing a mismatch. When this happens DKIM fails authentication on the receiver side because it is not added to outgoing mail.
I tried adding the reply-to and sender header manually to wp_mail() but it did not work. One had to do the following:
Right now i have to manually modify the /wp-includes/pluggable.php file in the wp_mail() function to include:
if (strlen($phpmailer->Sender)==0)
{
$phpmailer->Sender = $phpmailer->From;
$phpmailer->AddReplyTo($phpmailer->From);
}
This resolves the problem and DKIM works again.
Change History (16)
#2
@
13 years ago
Yes, understandable and i was already aware of pluggable being able to be re-defined in a plugin but i figured having those few extra lines in the pluggable.php in future releases could improve security out of the box instead of having users scrambling around in hopes of a patch plugin existing (or needing to be made) to do such a simple thing so DKIM support can function normally.
Notice the new lines dont affect WP at all it just now makes all outgoing mail "properly formatted" so that the server can include a valid DKIM signature (if they so choose).
#3
@
13 years ago
- Keywords needs-patch added
- Milestone changed from Awaiting Review to Future Release
Sure, makes sense.
#6
@
13 years ago
The bug, '#21659 - wp_mail() problem with Reply-To header', is also related with this one.
I found something wrong when I click the 'Reply' button on the email sent from Grunion Contact Form module of Jetpack plugin in GMail. The reason is wp_mail() doesn't deal with 'Reply-To' header.
#7
@
12 years ago
This is no longer a minor or cosmetic bug since Gmail changed their spam filters (~1 month ago).
If using EXIM mail server (the default mail server for cPanel), all emails sent to Gmail will either be silently discarded, or sent as spam. Postfix works fine as it automatically sets the Sender header, and the issue may also occur with other mail servers as well.
#9
@
11 years ago
Is this a Google-specific thing regarding the Sender header? Or for any receiving MTAs that are using DKIM + DMARC?
And is it relevant only when the sending MTA applies DKIM to the message? What if DKIM is not used by the sender?
If anyone could supply links to official methods of handling this issue, that would be useful.
#11
follow-ups:
↓ 12
↓ 13
@
10 years ago
I can see the possibility of changing this so that in the default everything matches. However, there's not a need to modify the function (pluggable or otherwise) as @kellogg9 mentioned. The phpmailer settings can be handled with the phpmailer_init action.
phpmailer_init fires after PHPMailer is initialized. So the action can be used to cleanup any settings as needed. I believe that until a full fix is in place, the following would patch it:
add_action( 'phpmailer_init', 'my_phpmailer_dkim_cleanup' );
function my_phpmailer_dkim_cleanup( $phpmailer ) {
if ( '' == $phpmailer->Sender ) {
$phpmailer->Sender = $phpmailer->From;
$phpmailer->AddReplyTo( $phpmailer->From );
}
}
#12
in reply to:
↑ 11
@
10 years ago
I've been using a similar snippet for a while but without the Reply-To header; adding it makes DKIM to fail for me.
Replying to cbutlerjr:
I can see the possibility of changing this so that in the default everything matches. However, there's not a need to modify the function (pluggable or otherwise) as @kellogg9 mentioned. The phpmailer settings can be handled with the phpmailer_init action.
phpmailer_init fires after PHPMailer is initialized. So the action can be used to cleanup any settings as needed. I believe that until a full fix is in place, the following would patch it:
add_action( 'phpmailer_init', 'my_phpmailer_dkim_cleanup' ); function my_phpmailer_dkim_cleanup( $phpmailer ) { if ( '' == $phpmailer->Sender ) { $phpmailer->Sender = $phpmailer->From; $phpmailer->AddReplyTo( $phpmailer->From ); } }
#13
in reply to:
↑ 11
@
10 years ago
Hi @cbutlerjr ... thanks for the reply. A few years back, about a year after i opened this bug ticket, i stumbled upon the phpmailer_init() action and implemented a virtual identical version that you wrote (shown below). It has been working ever since. Thanks for adding this to my ticket. I guess i should have added an update here a few years back. Here is hoping though that the core team finally adds the fix into their official build.
~Kimberly
add_action( 'phpmailer_init', 'my_phpmailer_dkim_cleanup' );
function my_phpmailer_dkim_cleanup( $phpmailer ) {
if ( '' == $phpmailer->Sender ) {
$phpmailer->Sender = $phpmailer->From;
$phpmailer->AddReplyTo( $phpmailer->From );
}
}
#14
@
3 years ago
- Keywords close 2nd-opinion added
- Milestone set to Awaiting Review
I came across this one going through a list of tickets that have lost their milestone at some point. Re-adding one to help surface this one in reports.
I'm not sure how I'd go about testing this issue locally, but here are a few thoughts.
PHPMailer has undergone some big changes since this ticket was created, and WordPress is now on the latest version of the library (6.x) after the work in #41750. It would be great if someone could test for this issue using the latest version of WordPress (6.0 at the time of this comment) to see if this problem still exists.
DKIM is not something configured or used by default for WordPress sites. The wp_mail() function tries to be as generic as possible to work on as many sites as possible, and as far as I can tell, wp_mail() does not have any considerations for any specific authentication type.
All this said, I'm leaning towards closing this out as something that should be handled by a plugin, or the custom code configuring DKIM in PHPMailer.
This ticket was mentioned in Slack in #core by abhanonstopnews. View the logs.
2 years ago
#16
@
3 months ago
- Keywords needs-patch removed
- Resolution set to worksforme
- Status changed from new to closed
Reproduction Report
Description
❌ This report can't validates that the issue can be reproduced.
Environment
- WordPress: 6.9-alpha-60609
- PHP: 8.2.29
- Server: Apache/2.4.62 (Debian)
- Database: mysqli (Server: 8.0.43 / Client: mysqlnd 8.2.29)
- Browser: Chrome 138.0.0.0
- OS: Windows 10/11
- Theme: Twenty Twenty-Five 1.3
- MU Plugins: None activated
- Plugins:
- Test Reports 1.2.0
Testing Instructions
- Add a local server like Postfix with DKIM to your local wordpress site
- Send email to a Gmail address (which has full DKIM/SPF testing)
- ❌ Email is received without troubles.
- ❌ Also tested towards https://www.mail-tester.com/ with the Health Check plugin (Tools), Result: 10/10
Actual Results
- ❌ Error condition is not occurring
Additional Notes
I've been testing with some Docker containers using WP and Postfix (I will be testing with other alternatives like sendmail and qmail onwards)
With a fresh installation, both WP and Postfix, not explicitely specifiying a Sender envelope fully relying on the mail function "as-is", this is an example email, sent from my server to my gmail account
Delivered-To: [REDACTED_EMAIL]
Received: by 2002:a05:6359:6c93:b0:1ff:db44:3f60 with SMTP id td19csp77717rwb;
Wed, 6 Aug 2025 06:05:48 -0700 (PDT)
X-Google-Smtp-Source: AGHT+IHuqeZlSnkdrM0/F3klNm20amzDRETPIQrSfJOabE105QzLv0wAZut5j5aY3jWhSk+i4XGR
X-Received: by 2001:a06:6512:ac2:b0:553:cf7d:72a0 with SMTP id 2adb3069b0e04-55caf51e0f4mr1045577e87.5.1754485548059;
Wed, 06 Aug 2025 06:05:48 -0700 (PDT)
ARC-Seal: i=1; a=rsa-sha256; t=1754485548; cv=none;
d=google.com; s=arc-20240605;
b=eNclUcCzbSfNCdBtNo/99LU4elhYf05nti7DCra25Zq7ySU0lnh7aAqbzAiBVCv/VU
05zv7j8gVWP9obXxKH8kuF0lh8dSpvk3/69pVO2hj+AY5pdM/m21wZpCsLSvQxnAWMev
ZbVYgEoqASFSia9jEWxHsXvH/v1hKsKF3pVx1r52uQaCk8TvquHuf/Z/UwVwZ7IGiaRU
FlYOP5HV9wmAGPjHQCmAakNK8afdff3cSbha6ydpWSuEuXoXUNJ1lSKXZRdBs1C8q18W
7hIIgWj+QIaZoH9Tpj11WYSBKwjXoq0Xbc4XAYrUrDRLLBZ2lqE6pStFnxugsgq3tXxZ
66pQ==
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605;
h=mime-version:message-id:from:date:subject:to:dkim-signature;
bh=PVNFHtbm7C0KnKg1qneS9ozOqv1xDi0783HTk5AXZgM=;
fh=LnWiZB+0qsThBew1oCwmWb63UJ40SUAv5hSa6DrXbks=;
b=FH2iYY9G42wmantVhhqI2QtyQvFwWE65CWWSNHHCHdjlIatKcxDRWIpj/pz0sfKqyW
vkG2G7RANuUqXhT+SifGICbbFd/d+yLQoE4NhxrREr2pjIzBMmekPDGh1qVMq7UQ72Ju
KOIx48rUzKrp80EKuL2ZiLLjHifGUKgSJAXQ95SiuPOEIbkeGr6V24OTw3U+9KOe1vVV
0+HRoZepT7sjx1iQV1P1CNoij+VYPElBd6rzFB6jKqNrsQM26a6S4U8CdeyOpoPVd6cb
o6LmbfnMggOyoudva/6hG/CP+Sxsk/X8BE8/vSPxhMxipW+NvDd2npaIZTbKRdnaAVKD
ckOw==;
dara=google.com
ARC-Authentication-Results: i=1; mx.google.com;
dkim=pass header.i=@[REDACTED_SERVER] header.s=mail header.b=jPKZXw5o;
spf=pass (google.com: domain of www-data@[REDACTED_SERVER] designates [REDACTED_SERVER_IP] as permitted sender) smtp.mailfrom=www-data@[REDACTED_SERVER];
dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=[REDACTED_SERVER]
Return-Path: <www-data@[REDACTED_SERVER]>
Received: from [REDACTED_SERVER] ([REDACTED_REVERSE_HOST]. [[REDACTED_SERVER_IP]])
by mx.google.com with ESMTPS id 2adb3069b0e04-55b889ce3ddsi4183363e87.634.2025.08.06.06.05.47
for <[REDACTED_EMAIL]>
(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
Wed, 06 Aug 2025 06:05:47 -0700 (PDT)
Received-SPF: pass (google.com: domain of www-data@[REDACTED_SERVER] designates [REDACTED_SERVER_IP] as permitted sender) client-ip=[REDACTED_SERVER_IP];
Authentication-Results: mx.google.com;
dkim=pass header.i=@[REDACTED_SERVER] header.s=mail header.b=jPKZXw5o;
spf=pass (google.com: domain of www-data@[REDACTED_SERVER] designates [REDACTED_SERVER_IP] as permitted sender) smtp.mailfrom=www-data@[REDACTED_SERVER];
dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=[REDACTED_SERVER]
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=[REDACTED_SERVER]; s=mail; t=1754485547; bh=PVNFHtbm7C0KnKg1qneS9ozOqv1xDi0783HTk5AXZgM=; h=To:Subject:Date:From:From; b=jPKZXw5oug02Vb8SUz6gARY3DIvxpfyeYQ9WrBNCJzFPM5j+w/IXeq07HRp7tGp4S
Rbjux3ukwRSySmCaHJquXDemblwAiuYg8O92cdA6nJCPRxR1Xem5GAyCRfKgxm3id/
kJJvr1sIxKB8qD0FuZkIolZ7PBBzceTRHuerOlMk=
Received: by [REDACTED_SERVER] (Postfix, from userid 33) id 4BF5E21C00; Wed,
6 Aug 2025 13:05:47 +0000 (UTC)
To: [REDACTED_EMAIL]
Subject: New WordPress Site
Date: Wed, 6 Aug 2025 13:05:47 +0000
From: WordPress <wordpress@[REDACTED_SERVER]>
Message-ID: <JDwgW5Y3fXqkMKrRaj7tfaCsvGdzntxFxMknqoTVHyE@[REDACTED_SERVER]>
X-Mailer: PHPMailer 6.9.3 (https://github.com/PHPMailer/PHPMailer)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Your new WordPress site has been successfully set up at:
https://[REDACTED_SERVER]
You can log in to the administrator account with the following information:
Username: admin
Password: The password you chose during installation.
Log in here: https://[REDACTED_SERVER]/wp-login.php
We hope you enjoy your new site. Thanks!
--The WordPress Team
https://wordpress.org/
As we can clearly see here, all DKIM and SPF tests are passing without troubles.
Why so?
Because PHP's mail function uses the -t parameter which takes From: for the sender envelop in the headers. At the same time, PHPMailer current version (6.9.3), takes the default from wordpress@site_hostname and sets is as a From: header. This is why everything can be perfectly identified, and the Reply-To is not really needed for DKIM/SPF authentication/confirmation.
Although not having the -f in mail could be a consequence for some old versions of sendmail and certain secondary SMTP servers (like msmtp), could be causing to fail because they cannot correctly parse the headers for the Sender hence resulting in an invalid sender envelope.
I'm closing this ticket as worksforme. But this will be further tested in the following ticket #49687, because any further testing here could duplicating efforts instead of having all concentrated in a single one.
Note that functions in pluggable.php are called pluggable because you can re-define them in a plugin, so that you don't have to hack Core.