|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #19538 No way to identify source of email sent by mail()
Submitted: 2002-09-21 07:54 UTC Modified: 2003-02-26 14:13 UTC
Avg. Score:4.2 ± 1.1
Reproduced:10 of 11 (90.9%)
Same Version:9 (90.0%)
Same OS:9 (90.0%)
From: misiek at pld dot org dot pl Assigned:
Status: Closed Package: Feature/Change Request
PHP Version: 4.2.3 OS: ALL
Private report: No CVE-ID: None
 [2002-09-21 07:54 UTC] misiek at pld dot org dot pl
The problem is that when any user sends email message from php script it always comes from ,,http'' (or whatever) user.

There is no way to identify which script was used to send some mail. User sets all headers as he wants ;/ Sender is http@fqdn.

On my systems users have a lot of php scripts and spammers use them to spam through my server! Identifying which script was used is quite problematic when there are tons of scripts. php currently doesn't give any information about which script was that - there is no usefull enviroment variables, there is no additional mail headers, working directory when calling sendmail is ,,/'' so I can't even do pwd to identify directory with php script.

I'm suggesting adding way to identify source script. I thing about two ways of doing this:
1) set enviroment variable SCRIPT_FILENAME with same value as in php (and other variables) before executing sendmail so It would be possible to setup wrapper instead of sendmail and do whatever you want.
2) add option to php.ini like sendmail_id_header = yes|no
that would cause adding some header to message like X-PHP-Script-Filename: /home/something/blah.php
or even sendmail_id_header = name of php variable
(that would cause to add X-Name-Of-PHP-Variable: it's value to mail message).
Second is better because it works with SMTP, too.



Add a Patch

Pull Requests

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2002-09-21 12:19 UTC] spam at bartosz dot net
I suggest to add also sender IP as example
 [2002-09-21 12:35 UTC]
I've been thinking... and I don't think it's any useful to add those things.
This is because it can be very easily compromised by just using popen("sendmail") or similar.
 [2002-09-21 13:28 UTC] misiek at pld dot org dot pl
I'm running safe_mode so executing/popening sendmail is not possible (theoretically).

It's really very usefull. Now there is completly no way to identify source of mail.

Also note that in most cases _not_ mine users are those who are spamming but other people through typical mail.php scripts (forms) put on web by mine users. Identifying script would allow me to fix it/protect or just tell user to remove it.
 [2002-09-21 13:32 UTC]
Makes sense then... I'll have a look.

 [2002-09-21 19:51 UTC] xx-nospam-php at BrazilianTranslation dot net
IMHO, sendmail's (or whatever MTA you're using) logs should give that kind of information away, not headers produced by PHP.

Luciano ES
Santos, SP - Brasil
 [2002-09-22 04:58 UTC] misiek at pld dot org dot pl
Sorry but you are simply wrong. MTA logs don't contain any usefull information.
 [2002-10-23 15:09 UTC] beckman at purplecow dot com
This is easily solved:

mail("","Subject Line","Body","X-PHP-Mailer-Script: {$_SERVER[HTTP_HOST]}{$_SERVER[REQUEST_URI]}\nX-PHP-Mailer-Path: {$_SERVER[SCRIPT_FILENAME]}\nX-PHP-Remote-IP: {$_SERVER[REMOTE_ADDR]");

This will add three new headers to this mail:

X-PHP-Mailer-Path: /real/path/to/script.php

And now you'll know which script the spammer is using.
 [2002-10-23 16:01 UTC] misiek at pld dot org dot pl
I can't modify my customers scripts. Scripts are changing frequently, new customers upload new scripts and so on. Anyway:
[root@gucio customers]# grep -ri 'mail(' . | wc -l

Changing 2873 not mine script means ,,introduce some bugs'', too.

Basically I want feature that does similar thing to yours but configurable globally from php.ini.
 [2002-10-23 17:24 UTC] beckman at purplecow dot com
Ah, I see.  So you want to be able to have a php.ini directive like this:

  add_mail_headers = "X-PHP-Script: {$_SERVER[HTTP_HOST]}{$_SERVER[REQUEST_URI]}\nX-Contact-If-Spammed: Contact Information\n";

So that every mail() call will add that line.  I think that is a valid request, especially since a badly formed script can really mess things up.  It would default to "", and if it was not properly written it would be ignored.

By making it configurable, admins can choose to add or remove global mail headers.  I think this would be very useful for installs which serve lots of customers.
 [2002-10-23 17:30 UTC] misiek at pld dot org dot pl
Thats exactly it! Derick assigned this task but he is afaik busy and won't implement this soon. Too bad but I'm patient :-)
 [2002-10-24 00:28 UTC]
Unassign from me, I've no time right now.

 [2002-10-29 14:55 UTC] misiek at pld dot org dot pl
Ok, here is simplest verion of what I requested - unfortunately it's not configureable. I hope that code is ok (is it in terms of php codding?)

diff -urN php-4.2.3/ext/standard/mail.c
---   Tue Oct 29 21:35:04 2002
+++ php-4.2.3/ext/standard/mail.c       Tue Oct 29 21:33:03 2002
@@ -21,6 +21,8 @@
 #include <stdlib.h>
 #include <ctype.h>
 #include <stdio.h>
+#include <syslog.h>
+#include <string.h>
 #include "php.h"
 #include "ext/standard/info.h"
 #if !defined(PHP_WIN32)
@@ -37,6 +39,10 @@
 #include "safe_mode.h"
 #include "exec.h"
+#include "zend_operators.h"
+#include "zend_globals.h"
 #ifdef PHP_WIN32
 #include "win32/sendmail.h"
@@ -166,8 +172,42 @@
                efree (sendmail_cmd);
        if (sendmail) {
-               fprintf(sendmail, "To: %s\n", to);
-               fprintf(sendmail, "Subject: %s\n", subject);
+               if ((to != NULL) && (strlen(to)!=0)) { 
+                       fprintf(sendmail, "To: %s\n", to);
+               }
+               if ((subject != NULL) && (strlen(subject)!=0)) {
+                       fprintf(sendmail, "Subject: %s\n", subject);
+               }
+               TSRMLS_FETCH();
+               if (PG(http_globals)[TRACK_VARS_SERVER]) {
+                       zval **remote_addr, **server_name, **server_port,
+                               **request_uri, **http_user_agent;
+                       if (zend_hash_find(PG(http_globals)[TRACK_VARS_SERVER]->, "REMOTE_ADDR", sizeof("REMOTE_ADDR"), (void **) &remote_addr)==SUCCESS) {
+                               convert_to_string_ex(remote_addr);
+                               fprintf(sendmail, "HTTP-Posting-Client: %s\n", Z_STRVAL_PP(remote_addr));
+                       }
+                       if (zend_hash_find(PG(http_globals)[TRACK_VARS_SERVER]->, "SERVER_NAME", sizeof("SERVER_NAME"), (void **) &server_name)==SUCCESS) {
+                               convert_to_string_ex(server_name);
+                               fprintf(sendmail, "HTTP-Posting-URI: %s", Z_STRVAL_PP(server_name));
+                               if (zend_hash_find(PG(http_globals)[TRACK_VARS_SERVER]->, "SERVER_PORT", sizeof("SERVER_PORT"), (void **) &server_port)==SUCCESS) {
+                                       convert_to_string_ex(server_port);
+                                       fprintf(sendmail, ":%s", Z_STRVAL_PP(server_port));
+                               }       
+                               if (zend_hash_find(PG(http_globals)[TRACK_VARS_SERVER]->, "REQUEST_URI", sizeof("REQUEST_URI"), (void **) &request_uri)==SUCCESS) {
+                                       convert_to_string_ex(request_uri);
+                                       fprintf(sendmail, "%s", Z_STRVAL_PP(request_uri));
+                               }
+                               fprintf(sendmail, "\n");
+                       }
+                       if (zend_hash_find(PG(http_globals)[TRACK_VARS_SERVER]->, "HTTP_USER_AGENT", sizeof("HTTP_USER_AGENT"), (void **) &http_user_agent)==SUCCESS) {
+                               convert_to_string_ex(http_user_agent);
+                                       fprintf(sendmail, "HTTP-Posting-User-Agent: %s\n", Z_STRVAL_PP(http_user_agent));
+                       }
+               }
                if (headers != NULL) {
                        fprintf(sendmail, "%s\n", headers);
[misiek@arm ~]$
 [2003-02-26 14:13 UTC]
Please try using this CVS snapshot:
For Windows:

From PHP 5 you can force this to be set with the ini setting "mail_force_extra_parameters", see also:


 [2003-02-26 14:13 UTC]
This bug has been fixed in CVS.

In case this was a PHP problem, snapshots of the sources are packaged
every three hours; this change will be in the next snapshot. You can
grab the snapshot at
In case this was a documentation problem, the fix will show up soon at

In case this was a website problem, the change will show
up on the site and on the mirror sites in short time.
Thank you for the report, and for helping us make PHP better.

PHP Copyright © 2001-2023 The PHP Group
All rights reserved.
Last updated: Sun Dec 10 08:01:28 2023 UTC