# Outgoing Spam cPanel: Find the Source and Stop It

Source: https://srvscripts.com/guides/find-source-of-outgoing-spam-cpanel/
Updated: 2026-10-03
Publisher: srvScripts (https://srvscripts.com/)

## Stop the bleeding

Pause outbound delivery so you are not making the blacklist situation worse while you investigate. This does not lose mail; it queues it:

In short: Pause outbound delivery so you are not making the blacklist situation worse while you investigate.

```
whmapi1 configureservice service=exim enabled=1 monitored=0
exim -bpc            # how many in the queue
exim -bpr | grep -c frozen
```

Then freeze everything currently queued so nothing goes out until you have looked at it: `exim -bpr | awk '/^ *[0-9]+[mhd]/{print $3}' | xargs -r exim -Mf`. You can thaw the legitimate messages later with `exim -Mt`.

## There are only four ways spam leaves a cPanel server

Every outbound message goes through one of these, and Exim logs which one. Check them in this order because it matches how often each one is the cause:

**1. A compromised mailbox (SMTP AUTH).** Someone phished a customer’s email password and is sending through your server with it. In `exim_mainlog` these lines carry `A=dovecot_login:user@domain`:

```
grep -Eo 'A=dovecot_(login|plain):[^ ]+' /var/log/exim_mainlog | sort | uniq -c | sort -rn | head
```

A real user sends tens of messages a day. A compromised one sends thousands, usually from many countries. Confirm with `grep 'A=dovecot_login:victim@domain' /var/log/exim_mainlog | grep -Eo '\[[0-9.]+\]' | sort | uniq -c | sort -rn | head`.

**2. A PHP script (a hacked WordPress plugin, a contact form abused as a relay).** cPanel’s Exim records the script’s working directory:

```
grep -Eo 'cwd=/home[^ ]+' /var/log/exim_mainlog | sort | uniq -c | sort -rn | head
```

If the top entry is `/home/user/public_html/wp-content/uploads/…` or a random directory name, that is your malware. `ls -la` it, check the file dates, and look at `/home/user/access-logs/` for POST requests to that file.

**3. A cron job or CLI script.** Same `cwd=` search but the directory will be outside `public_html`, and the `U=` field shows the system user: `grep -Eo ' U=[^ ]+' /var/log/exim_mainlog | sort | uniq -c | sort -rn`.

**4. Forwarders and auto-responders bouncing spam.** If the queue is full of bounces (`<>` sender) to addresses that do not exist, a catch-all forwarder or an auto-responder is replaying incoming spam back out. `exim -bpr | grep -c '<>'` — if that number is most of the queue, find the forwarder in `/etc/valiases/<domain>`.

The [exim-mail-queue-report](/scripts/exim-mail-queue-report/) script runs all four checks and prints the top offenders in one go.

## Shut the source down

- Compromised mailbox: change the password in WHM → List Accounts → cPanel → Email Accounts, or `uapi --user=cpuser Email passwd_pop email=victim domain=domain.com password='New!Pass'`. Then suspend outgoing mail for the whole cPanel account until the customer has confirmed the new password everywhere: `whmapi1 suspend_outgoing_email user=cpuser` (reverse with `unsuspend_outgoing_email`). Check for a forwarder the attacker added to keep receiving copies.

- Malicious script: move it out of the web root (do not just delete — you may need it for the customer), `chmod 000` the directory, and run `imunify360-agent malware user scan --user=cpuser` or `maldet -a /home/cpuser/public_html`. Update the CMS and every plugin before re-enabling.

- Forwarder loop: remove the catch-all (`:fail:` is the right default in Email Routing), and delete the auto-responder.

## Clean the queue

Delete what is clearly spam and release the rest:

```
exim -bpr | grep '' | awk '{print $3}' | xargs -r exim -Mrm
exim -bpr | grep 'frozen' | awk '{print $3}' | xargs -r exim -Mrm     # frozen = bounces that cannot deliver
exim -bpr | awk '/^ *[0-9]+[mhd]/{print $3}' | xargs -r exim -Mt      # thaw the rest
whmapi1 configureservice service=exim enabled=1 monitored=1
```

## Get off the blacklists and stop the next one

Request delisting only after the source is gone; Spamhaus and Microsoft re-list within hours if it is not. Then set the limits that would have caught this early: WHM → Tweak Settings → Max hourly emails per domain (200 is plenty for most customers), Track email origin via X-Source headers on, and Prevent “nobody” from sending mail on. Turn on **Mail limiting** alerts in WHM → Contact Manager so you get an email the moment an account hits its hourly cap instead of finding out from a blacklist.

Diagram: Find the top sender in exim_mainlog, identify whether it is a login, a script or forwarding, fix it, clear the queue and delist.

## Outgoing spam cPanel at a glance

**Official documentation:** [cPanel & WHM documentation](https://docs.cpanel.net/), [RFC 5321 (SMTP)](https://www.rfc-editor.org/rfc/rfc5321), [Linux man pages](https://man7.org/linux/man-pages/).

**Related guides:** [Choosing a VPS for a cPanel or DirectAdmin server in 2026](https://srvscripts.com/guides/best-vps-for-cpanel-directadmin-server/) · [Exim 4.99/4.100 on cPanel and DirectAdmin: the 2026 security fixes and what changed for admins](https://srvscripts.com/guides/exim-4-100-security-fixes/) · [Roundcube “database error” and webmail login loops on cPanel](https://srvscripts.com/guides/roundcube-database-error-login-loop/).
