Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Is there any way for me to find the php script that is sending emails.

I have apache+php ( no mod_suphp neither suexec ) in a "standard" install, and i want to find out witch php script is sending emails, when i check the logs i just see the uid of the user that's sending the emails ( in my case apache ) but i want to find out the script that's originated the email.

Is it possible or i must install suexec or mod_suphp to keep trac of that ?

Thks for the help.

share|improve this question
up vote 8 down vote accepted

php 5.3 was slotted to get better mail tracing, but I'm not sure if that happened. (edit: yes php 5.3 has logging built in now - php.ini has the config variable mail.log which will log use of mail from php code.)

We solved the problem by making sendmail a wrapper shell script.

In php.ini set a new mailer. E.g.:

sendmail_path = /usr/local/bin/sendmail-php -t -i

The sendmail-php script simply uses logger to get info, and then calls the system's sendmail:


logger -p -t sendmail-php "site=${HTTP_HOST}, client=${REMOTE_ADDR}, script=${SCRIPT_NAME}, filename=${SCRIPT_FILENAME}, docroot=${DOCUMENT_ROOT}, pwd=${PWD}, uid=${UID}, user=$(whoami)"

/usr/sbin/sendmail -t -i $*

This will log to whatever your is set to in the syslog.conf file.

Another suggestion is to install suhosin php extension to tighten up loopholes in PHP, unless you are running Debian or Ubuntu where this is already the default.

share|improve this answer
php 4.x here ( got some old apps that not viable porting to php 5.x ) – adam Apr 7 '10 at 13:49
No problem, this wrapper will do the trick. It is external to php. I mentioned php 5.3 merely as this lack of a logging feature was slated to be fixed by then. The wrapper works very well and we were able to pinpoint a flawed script by a user which was permitting spam. – labradort Apr 7 '10 at 13:53
thks, i guess i'm going to take your approach. thank you – adam Apr 7 '10 at 13:55
Hi, dont now why but the "script=${SCRIPT_NAME}, filename=${SCRIPT_FILENAME}" is not returning anything see: 7 20:24:08 gateway logger: sendmail-php: client=,filename=, pwd=/var/www/html/mail, uid=48, user=apache – adam Apr 7 '10 at 18:34
Are you sure it was set up correctly? If it was unknown as a predefined variable in your PHP environment, you should be seeing also: "script=," in the logged output. Check what you set up again very carefully. You could try: $_SERVER['SCRIPT_FILENAME'] You might be able to look up more variables for logging from the PHP documentation on Predefined variables: – labradort Apr 7 '10 at 19:19

The solution to this actually requires a few steps. labradort's solution above doesn't actually work since the logger script is a bash script, not php, and the bash script has no access to php's variables, so the logs come out blank. Basically whatever you want to log needs to be saved to environment variables in php prior to sending the email so the logger has access to the data. Since you're trying to detect other user's scripts, not necessarily your own, you have no control over the php code, so you need to use PHP's auto_prepend_file feature to ensure that all executed php runs your initialisation code before everything else. I prepended the following code via php.ini to ensure I have the data I need in the logger:

 * This passes all SERVER variables to environment variables, 
 * so they can be used by called bash scripts later
foreach ( $_SERVER as $k=>$v ) putenv("$k=$v");

I put together a full tutorial on how to get this working here:

share|improve this answer
The wrapper script did work on Redhat and Debian Linux's implementation of php defaults back when it was php 5.2 and earlier. I'm simply using mail.log = /var/log/apache-mail.log these days and it does what I need. – labradort Jun 18 '14 at 13:05
This is precisely how the shellshock bug is exploited. I seriously don't recommend doing things this way. – Ben Hitchcock Oct 9 '14 at 0:57
You have a point. You could certainly run the variables through a sanitise function to strip out anything harmful, like "() { :;};". Actually probably a good idea to prefix the variable names as well, with something like "PHP_", just in case there's an environment variable name clash. – Tom McQuarrie Oct 9 '14 at 3:44

There is a patch for PHP that will show which script is generating the emails by adding a header to the email being sent. I haven't tested it since I'm not keen on patching core PHP, but I've heard good things.

share|improve this answer
This sounds like an excellent way to go. +1. However, if you're managing a shared host with multiple clients, you may want to inform those clients about the header, or redirect the output into a log file instead. – Pekka 웃 Apr 7 '10 at 12:11
Yes maybe it's the way to go but at a certain point it my be a security issue, all the people is going to now what script is sending email, poorly made script's is just inviting to get hacked. Redirect to a log maybe it's better – adam Apr 7 '10 at 13:45
Poorly made scripts shouldn't be on the server in the first place, people will find them if they are there (particularly if they are part of a popular cms system). But I get your point that there is maybe a case against this solution. – kaerast Apr 7 '10 at 18:55

You're going to have to grep the access logs for something that fits the timeframe of when the messages were added to the spool.

share|improve this answer
thks for the replay, the problem is that is a shared hosting and for each domain the is a dedicated access log. – adam Apr 7 '10 at 12:04
Yes, unfortunately you're going to have to grep through all of them. – Richard Salts Apr 7 '10 at 22:31

May be just search through source files for "mail(" substring?

share|improve this answer
That is sometimes worth looking at, and in particular looking at the source code surrounding it for any vulnerabilities for spammers to use. But with lots of complicated php scripts owned by many people on a shared host, it's not the solution for this problem. – kaerast Apr 7 '10 at 12:49
In a shared hosting environment this might not pin-point the exact script or might result in multiple false positives – Eric Kigathi May 25 '15 at 20:08

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.