Stolen SMTP Credentials in Your WordPress Mail Plugin

By · Updated · 4 min read

You cleaned the site thoroughly and the spam kept going out. You searched for a mailer script and found nothing. Then your email provider tells you the messages came through your own account, authenticated correctly, from an address that is not yours. The credentials were stolen from your site, and they work perfectly well from anywhere in the world.

How the credentials get taken

WordPress sites routinely send mail through an external provider rather than the server's own mail function, because deliverability is better. Configuring that means storing a username and password — usually in a mail plugin's settings, which keeps them in the database, or occasionally in wp-config.php.

Anyone who can read your database or your files can read those credentials. A web shell, a database dump taken through an injection flaw, an exposed configuration file, or an administrator account the attacker created — all of them lead to the same place. Many mail plugins store the password in a form that is readable rather than genuinely encrypted, because the site has to be able to use it.

Why this is different from a mailer script

A mailer script runs on your server, so deleting it stops the sending and the evidence sits in your server's mail logs. Stolen SMTP credentials are used from the attacker's own infrastructure, so there is nothing on your server to delete and nothing in your server's mail queue to find.

That is why a thorough cleanup appears to fail. You did clean the site; the sending was never happening on the site. The tell is where the messages appear — in your email provider's sent history or outbound logs rather than in your server's mail queue. My guide on finding a mailer script covers the other scenario, and distinguishing the two early saves a lot of wasted searching.

Confirming it

Check your email provider's account activity: sent message volume, outbound logs, and authentication history including source addresses. Mail you did not send, authenticated with your credentials from an address you do not recognize, settles the question immediately.

Then work out which credentials are involved. Look at every mail plugin configured on the site, at any transactional email service integration, and at credentials stored in your configuration file or environment. Sites often have more of these than the owner remembers — an old plugin left configured, a form plugin with its own SMTP settings, a marketing integration from a campaign that ended.

Stopping it

Change the password at the email provider immediately, which is the only action that actually stops the sending. If you are using an application-specific password or API key, revoke it and issue a new one rather than just changing your main account password, since the old key keeps working otherwise.

Then enable two-factor authentication on the email account, and check for changes the attacker may have made there — forwarding rules, filters that hide bounce messages, added recovery addresses, or connected applications. Those persist after a password change and are commonly overlooked.

Then deal with the site

The credentials came from somewhere, so the site is still compromised until proven otherwise. Do the full pass: replace core, plugins and theme from clean sources, sweep the database, delete administrator accounts you did not create, look for persistence, and rotate every other credential stored on the site — database, hosting, FTP and any API keys.

Assume anything stored in the site was read, not just the mail credentials. That is the working assumption whenever someone had database or file access, and it is covered in my guide on rotating credentials after a hack.

Reducing the exposure next time

Use an API key scoped to sending only, rather than your main mailbox password, wherever your provider supports it. A key that can send and do nothing else is much less damaging when it leaks, and it can be revoked without changing the password you use to read your own mail.

Use a dedicated transactional email service for the site's outgoing mail rather than your primary business mailbox, so a compromise of the site does not put your actual email account at risk. And keep an eye on your provider's sending volume, since an unexplained spike is usually the earliest signal available. If you want the underlying compromise found and closed properly, that is my malware removal service.

Common questions

How do I know if my SMTP credentials were stolen rather than a script sending?

Look at where the messages appear. Mail sent by a script on your server shows in the server's mail logs and queue. Mail sent with stolen credentials shows in your email provider's sent history and authentication logs, often from IP addresses you do not recognize, with nothing on your server at all.

Where does WordPress store SMTP passwords?

Usually in the database, in the settings of whichever mail plugin you use, and sometimes in wp-config.php. Many plugins store the password in a readable or trivially reversible form, because the site needs to use it — so anyone with database or file access can recover it.

Changing my site passwords did not stop the spam. Why?

Because the sending is not happening on your site. The attacker holds your email provider credentials and is using them from their own systems. Only changing the password or revoking the key at the email provider stops it.

Should I use an API key instead of my email password?

Yes, wherever your provider supports it. A send-only API key limits what a leaked credential can do, and it can be revoked independently without disturbing your ability to read your own mail. It is a meaningful reduction in blast radius for very little effort.

What else should I check at my email provider?

Forwarding rules, filters — particularly any that delete or hide bounce messages — added recovery addresses, and connected or authorized applications. All of those survive a password change, and any of them can let someone retain access or visibility after you think you have locked them out.