Current situation: PHP2Shell. Two critical PHP vulnerabilities (CVSS 9.2) allow malicious code without login. Patches since 21 October 2026.What to do now →

The Server Is Sending Spam: Finding the Causes

Undeliverable mails, blocklists, complaints: when your own server sends spam, a script or a hijacked mailbox is usually behind it. Here is how to find the source.

Last updated 6 min readDetection and forensics

In short: When the server sends spam, there is usually one of three causes: an injected or abused PHP script, a mailbox with a stolen password, or a misconfigured mail server. Secure some of the waiting mails, read their header lines and the mail log, and in most cases you will find the source. Then stop the sending, close the cause and only then request removal from blocklists.

When customers find your invoices in the spam folder

It rarely begins with a security notice. Usually customers get in touch who no longer receive your quotes, or the mailbox fills with bounce messages for mails that nobody ever wrote. Sometimes the hoster blocks sending and gives conspicuous mail traffic as the reason.

For the company, this quickly has noticeable consequences. If the server's address is on a blocklist, other mail servers also reject your genuine mails: invoices, order confirmations, password links from the shop. The domain's reputation suffers, and the damage grows with every hour the sending continues.

Spam sending is among the known consequences of a compromise. After PHP2Shell, the vulnerabilities CVE-2026-109618 and CVE-2026-109619 with code execution without logging in, that is one more reason to look more closely. However, spam is not a specific PHP2Shell indicator; there are no confirmed indicators of compromise. Further general signs are described in Am I already compromised?.

Three typical causes when the server sends spam

Cause Typical picture Where to look
Injected PHP script Mails without login, delivered locally via sendmail Header lines, PHP mail log, new PHP files
Abused form Mails via a contact or referral form to foreign recipients Access log of the form, header lines
Hijacked mailbox Sending with a valid login at the mail server Mail log with login name, login locations
Open mail server Foreign senders use your server as a relay Mail server configuration, external check

The first two causes concern the website, the third the mail accounts, the fourth the server configuration. The distinction is important because the countermeasures are completely different.

Reading the mail queue

On servers with Postfix, the queue shows what is currently waiting to be sent. The following commands only read:

# Show the contents of the queue (equivalent to mailq)
postqueue -p | tail -30

# Show the header lines of a single mail (insert the queue ID from the list)
sudo postcat -q -h QUEUE-ID

# Successful logins at the mail server with user name
sudo grep 'sasl_username=' /var/log/mail.log | awk -F'sasl_username=' '{print $2}' | sort | uniq -c | sort -rn | head

The header lines often reveal the source already. If the mail comes from a logged-in mailbox, the login name appears in the mail log. If a single account piles up there with logins from foreign countries, that mailbox's password has very probably become known. If, on the other hand, the mail was delivered locally, it usually comes from a script on the server.

If another mail server runs on your server, such as Exim, the commands are named differently, but the principle stays the same: view the queue, read header lines, count logins in the log. With shared hosting without shell access, ask the hoster in writing for an extract of the mail log and a few sample mails with complete header lines. Many hosters supply these details on request, because they themselves have an interest in ending the sending.

Secure some complete mails before you hold or empty the queue. They are evidence for the later analysis and for conversations with the hoster or blocklist operators.

Finding the responsible PHP script

If the sending runs through PHP, PHP's mail configuration helps. According to the PHP manual, mail.log logs every call of the mail() function with the full script path, line number, recipient and headers. mail.add_x_header additionally writes a header line X-PHP-Originating-Script with the user ID and file name into each mail.

; In php.ini or in the FPM pool, then restart all workers
mail.add_x_header = On
mail.log = /var/log/php/mail.log

The log file must be writable for the PHP process. The header line reveals a file name to recipients; switch it off again after the analysis if you do not want it permanently.

If an unknown file turns up as the sender, for example in the upload or cache folder, that is a hint of a webshell. How to classify such files is described in Recognizing and removing webshells. If, on the other hand, it is a known contact form, it was probably abused, for example because recipients or header lines are taken from form input. That is a bug in the code, not a break-in, but it must be fixed just as quickly.

Not all spam uses the mail() function. Malicious code can also open a connection directly to foreign mail servers. Then the sending shows up neither in the queue nor in the PHP mail log, but it does show up as outgoing connections on port 25. How to check these is covered under Checking a server's outgoing connections.

Stopping the sending and restarting cleanly

Once the source is found, the cleanup follows in this order:

  1. Hold the sending: Block the route concerned, that is, deactivate the script, lock the mailbox or hold the queue. Secure waiting mails as evidence.
  2. Close the cause: With a webshell, bring PHP to a fixed version (8.5.12, 8.4.27, 8.3.36, 8.2.35 or a confirmed backport), restart all workers and clean up the website. With a form, correct the code. With a mailbox, change the password and check the user's device.
  3. Look for further traces: Whoever sends spam via a webshell has often created further backdoors.
  4. Limit egress: Allow outgoing connections on port 25 only for the mail server, not for the web server user.
  5. Clean up blocklists: Only now request removal from the blocklist operators and briefly describe what was fixed.
Tip

Take this opportunity to check SPF, DKIM and DMARC for your domain. These DNS records determine which servers may send on behalf of your domain, and they make it harder for outsiders to abuse your sender address.

How does PHP SOS help?

  • We evaluate queue, header lines and mail logs and determine whether script, form, mailbox or configuration is the cause.
  • We stop the sending in a controlled way and secure evidence for the hoster and blocklists.
  • We clean up the website within malware removal and close the entry point.
  • We limit outgoing mail traffic at server level and support the removal from blocklists.

Frequently asked questions

How do I notice that my server is sending spam?

Typical are bounce messages for mails that nobody wrote, notices from the hoster, a full mail queue and customers who suddenly find your mails in the spam folder. Entries of your server's address on public blocklists are also a clear sign.

How do I find the PHP script that is sending spam?

PHP can log every call of the mail() function with the script path if mail.log is set. With mail.add_x_header, PHP also writes the script name into the header of each mail. In mails already sent or waiting, a look at the header lines helps.

Should I empty the mail queue immediately?

Not before you have secured some mails as evidence. The header lines often show which script or mailbox triggered the sending. Holding is usually better than deleting until the source is known.

How do I get off blocklists again?

First eliminate the cause, then request removal from the respective blocklist operators. Most require an explanation of what was fixed. Anyone who applies too early and keeps sending spam will be listed again.

Sources

Immediate contact

Every hour counts. Write to us now.

Briefly describe your system, PHP version and observation. We will get back to you, clarify the situation and work remotely until the incident is closed and documented.

Immediate help