PHPGangsta - Der praktische PHP Blog

PHP Blog von PHPGangsta


Bug in PHP 5.3.0’s mail() Funktion

with 4 comments

[Edit: Der Bug wurde mit 5.3.2 behoben, siehe Changelog http://www.php.net/ChangeLog-5.php#5.3.2: Fixed bug #50907 (X-PHP-Originating-Script adding two new lines in *NIX). (Ilia)]

Vielleicht hat noch jemand von euch das Problem. Ziel war einfach nur, eine kleine Mail von meinem Mac OS X aus PHP heraus zu versenden. Dazu ist hier PHP 5.3.0 installiert, ebenso wie ein Apache und ein Postfix.

Das Script sieht unspektakulär aus:

$headers = 	'From: source@mail.de' . "\n" .
			'To: target@mail.de' . "\n" .
			'Reply-To: source@mail.de' . "\n" .
			'X-Mailer: PHP/' . phpversion();
mail('target@mail.de', 'testmail!', $message, $headers, '-fsource@mail.de');

In der php.ini ist folgendes eingestellt:

sendmail_path = /usr/sbin/sendmail -t -i

Das Problem ist dabei, dass die Emails nicht korrekt ankommen. Alle Header, die ich oben angegeben habe, stehen im Body der Email. Es gibt also ein Umbruchproblem, irgendwo ist einer zuviel.

Return-Path: <source@mail.de>
Delivery-Date: Tue, 03 Nov 2009 14:39:05 +0100
Received: from server.de (server.de [111.111.17.10])
 by mx.server.de with ESMTP
 id 0LxhS3-1M6JqE0zvv-016hU3 for source@mail.de; Tue, 03 Nov 2009 14:39:05 +0100
Received: from ip-18-.provider.de (ip-18-.provider.de [222.222.248.46])
 by m.server.de with ESMTP
 id 0LjM2Z-1MTKv00Dgl-00d0Vo; Tue, 03 Nov 2009 14:39:05 +0100
Received: by ip-18-.provider.de (Postfix, from userid 1)
 id CF7181196C0; Tue, 03 Nov 2009 14:39:04 +0100 (CET)
To: target@mail.de
Subject: some subject
X-PHP-Originating-Script: 501:ErrorController.php
Message-Id: <0LjM2Z-1MTKffffgl-00d0Vo@m.server.de>
Date: Tue, 03 Nov 2009 14:39:05 +0100
X-Provags-ID: V01U2FsdGVrf1+XTUgdYEhFFTVVw58w3JV/CwkzzZnpRBZbnSR
 Rtupv2Jro7gRSvDH8j3QVDjBuBuAra893YNAvSVu/TgVETcVIT
 Y+uvNPgthhI6VXtHYzoCA==
X-PhishingScore:   0
 tests=
X-SpamScore: 2.9
 tests= TVD_SPACE_RATIO
Envelope-To: source@mail.de

From: source@mail.de
To: target@mail.de
Reply-To: source@mail.de
X-Mailer: PHP/5.3.0
Message-Id: <20091029555904.CF7181196C0@ip-18-.provider.de>
Date: Tue, 03 Nov 2009 14:39:04 +0100 (CET)

message here

Nach etwas rumprobieren, Suchmaschinen bedienen und genauerem Hingucken fällt einem das Problem auf:

PHP ergänzt die Header um einen Eintrag „X-PHP-Originating-Script“. Darin wird der Name des PHP-Scripts festgehalten, welches den mail()-Aufruf gemacht hat. Besonders interessant falls man sich einen fiesen Form-Mailer oder sowas eingefangen hat, und ihn nicht findet. Oder man hat andere Kunden mit ihren Projekten auf seinem Server, die Unfug treiben.

Dieser Header wird von PHP 5.3.0 mit einem „\r\n“ abgeschlossen, und danach folgen die anderen Header.
Da wir hier allerdings unter Mac OS X sind (sprich FreeBSD), wäre ein „\n“ besser. Das betriftt auch Linux etc.

Lösung des Problem ist also: Deaktivieren dieses Zusatzheaders in der php.ini:

mail.add_x_header = Off

Diese Option ist erst seit PHP 5.3.0 verfügbar. In meiner PHP-Version, die hier installiert ist, war das nämlich auf „On“ geschaltet. Im CVS von PHP ist der Bug berichtigt, aber eine 5.3.1 ist aktuell noch nicht released. Hier der Bug-Report, der damit zu tun hat.

Weitere Forenbeiträge zu dem Thema bei Nabble oder auf der Postfixbuch-Mailingliste.

Written by Michael Kliewe

November 4th, 2009 at 12:21 pm

4 Responses to 'Bug in PHP 5.3.0’s mail() Funktion'

Subscribe to comments with RSS or TrackBack to 'Bug in PHP 5.3.0’s mail() Funktion'.

  1. Gibt es einen Grund, weshalb du den „To:“-Header nochmal separat setzt? Der wird doch von PHP selbst gesetzt durch das erste Attribut der Funktion. In deinem Quelltext steht er auch doppelt drin.

    Bei dir ist auch bei „X-PHP-Originating-Script“ kein doppelter Umbruch und die doppelte Leerzeile ist genau vor deinem zweiten fehlerhaften „To:“-Header. Bist du dir sicher, dass das Problem der PHP-Header ist?

    Bastian

    8 Nov 09 at 08:35

  2. Wenn’s im Bugtracker steht wirds so sein ;o)
    Auch wenn das jetzt ein sehr kurzer Kommentar ist:
    Mir ist’s komischerweise noch nicht aufgefallen, werd ein Auge drauf haben – besten Dank!!

    PHP Agentur

    8 Nov 09 at 09:20

  3. Das mit dem To: Header stimmt, bin grad auch erstaunt warum es doppelt ist. Früher war es jedenfalls so, dass man das To: explizit setzen mußte, da der erste Parameter der mail() Funktion nur der Envelope-To ist (also die Zieladresse, die im SMTP-Protokoll beim RCPT-TO verwendet wird). Nun scheint es so zu sein, dass entweder php oder der SMTP diesen Header setzt.
    Sonst hattest du früher garkeinen To: Header.
    Auf php.net sieht man auch, dass dort der To: Header explizit gesetzt wird.
    http://de.php.net/manual/en/function.mail.php
    Da muß also irgendwer das selbstständig setzen in diesem Fall.

    Zu dem „nicht sichtbaren doppelten Umbruch“: Das war genau das, weshalb man es nicht auf den ersten Blick erkennen kann, woran es liegt. PHP hat an den Postfix das hier übergeben (gekürzt):

    Return-Path: source@mail.de\n
    Delivery-Date: Tue, 03 Nov 2009 14:39:05 +0100\n
    Received: from server.de (server.de [111.111.17.10])\n
    by mx.server.de with ESMTP\n
    id 0LxhS3-1M6JqE0zvv-016hU3 for source@mail.de; Tue, 03 Nov 2009 14:39:05 +0100\n
    To: target@mail.de\n
    Subject: some subject\n
    X-PHP-Originating-Script: 501:ErrorController.php\r\n
    From: source@mail.de\n
    To: target@mail.de\n
    Reply-To: source@mail.de\n
    X-Mailer: PHP/5.3.0\n
    Message-Id: <20091029555904.CF7181196C0@ip-18-.provider.de>\n
    Date: Tue, 03 Nov 2009 14:39:04 +0100 (CET)\n
    \n
    message here

    Es sind also überall \n, außer dem X-PHP-Originating-Script. Dies hat dann der Postfix „kaputt gemacht/falsch gepariert“, siehe auf php.net/mail

    Note: If messages are not received, try using a LF (\n) only. Some poor quality Unix mail transfer agents replace LF by CRLF automatically (which leads to doubling CR if CRLF is used). This should be a last resort, as it does not comply with » RFC 2822.
    Dadurch entsteht der doppelte Umbruch (CRCRLF).

    Der Ziel-SMTP hat dann beim Annehmen der Mail erkannt: Oh, da fehlen einige essentielle Header (da er ja nur die Header bis zum ersten Umbruch erkennt), dann ergänze ich das mal um die Message-Id und das Date. Außerdem ergänzt er seine eigenen Anti-Spam-Header und den Envelope-To. Dann entsteht genau die oben im Artikel abgebildete Mail beim Empfänger.

    Hoffe das war halbwegs verständlich erklärt 😉

    Michael Kliewe

    8 Nov 09 at 11:02

  4. Der Bug wurde mit 5.3.2 behoben, siehe Changelog
    http://www.php.net/ChangeLog-5.php#5.3.2

    Fixed bug #50907 (X-PHP-Originating-Script adding two new lines in *NIX). (Ilia)

    Michael Kliewe

    5 Mrz 10 at 11:24

Leave a Reply

You can add images to your comment by clicking here.