Check whether my WordPress site has been hacked or is vulnerable: core
files, PHP files in uploads, suspicious code, unknown administrators,
outdated plugins with known vulnerabilities. Explain in plain language what
you find and what you recommend. Don't change anything yet.
Your hosting account comes with a check that looks at all the places where a WordPress hack usually hides, in one go. The assistant uses it when you ask whether your site is safe. It only reads and changes nothing, so you can run it as often as you like.
Important to know up front: the result is a list of signals, not proof. Some signals have an innocent explanation. This article walks through them, so you know what you are looking at.
1. Are the core files still correct?
The files of WordPress itself are compared with the official versions from wordpress.org, file by file. A difference means something in a core file was changed, or a file was added that does not belong.
This is the strongest signal in the whole list. WordPress files are supposed to match exactly. An attacker who puts a backdoor in a core file always shows up here.
Innocent explanation: an interrupted update. Then files are missing instead of extra files being present.
2. PHP files in your uploads folder
wp-content/uploads is for images and documents. Not for PHP. A PHP file there is almost never innocent, because it is the easiest place to upload something and then call it.
If you find one, you have probably found the way in. Do not delete it straight away: back up first, then clean up, and look in your logs to see who requested it.
3. What is in mu-plugins?
The folder wp-content/mu-plugins holds plugins that are always active and that you cannot switch off in the admin panel. Ideal for an attacker, because your plugin list shows nothing of it.
The check shows you what is there. It does not say whether it is good or bad, because some hosting providers and some security plugins legitimately place something here. So the question is: do I recognise these files? If not, find out where they came from before you delete anything.
4. The first lines of index.php and wp-config.php
These two files are executed on every visit, which makes them a favourite with attackers. The check looks at the beginning of both files and searches there for functions that execute code coming from somewhere else.
If something is there, you see the start of the line in the output. A normal WordPress index.php is three lines of comment and one line of code. Anything that looks longer or more complicated does not belong.
5. Typical backdoor patterns across all your files
Next the check goes through all the PHP files of your site and looks for the combinations that occur almost exclusively in malicious code: code that executes encoded or compressed text, code that executes whatever is sent along in a web request, and variants where the function name itself is hidden behind character codes.
The cache folder is skipped, because it holds generated clutter that triggers false alarms.
6. Which PHP files changed in the last three days?
A hack changes files, and that change has a date. The check counts how many PHP files were modified in three days and then specifically lists the files that sit outside the normal places: not in plugins, not in themes, not in the WordPress folders.
Read this signal in context. If you just ran updates, a high number is normal. A modified file in an odd place, while you have done nothing for weeks, is not.
7. Who are your administrators?
Every account with administrator rights ends up in the list, with the date it was created. After that comes a separate signal for administrators added in the last fourteen days.
That is the signal to sit down with. An unknown administrator is a problem, but a familiar name may also have been created by someone legitimately helping out. Call or email whoever manages your site before you remove accounts.
8. Database triggers
This is the quiet one. A trigger in the database is a piece of logic that automatically does something when a table changes. WordPress does not use them. Some backdoors do, for instance to recreate an administrator on every new comment.
That is exactly why a site sometimes comes back after all the files have been cleaned. You dealt with the files and not with the database. If a trigger is there, you see it here.
9. Are your addresses still right?
Finally the two addresses from your settings are shown: the address of the site and the address of the front page. If a domain you do not recognise is in there, that explains visitors ending up somewhere else.
What the result means
At the bottom there is one line. Either no suspicious signals were found, or there were, in which case the advice is to contact your hosting provider before you start cleaning up.
That advice is there for a reason. Cleaning up in the wrong order makes it harder. If the way in is removed before anyone looked at how it was used, you do not know whether it also sits somewhere else.
What you do yourself
Back up first, always. Even an infected site. That is your evidence and your safety net.
Then the passwords. WordPress administrators, your hosting account, the database, FTP and every mail address you can reset a password with. A hack that comes back often comes back through a password that still works.
Then the versions. Outdated plugins are the most used way in. Update them, preferably with a snapshot beforehand, see safely update WordPress.
And schedule the check. You can ask the assistant to run it monthly and only email you when something comes out. The prompts page has an example of such a report.
Common mistakes
Reading signals as proof. A changed core file after an interrupted update is not a hack. Always read the explanation that comes with it.
Reading no signals as "I am safe". The check looks for known patterns in files and at a few places in the database. A tidy, fresh backdoor can slip through. Combine it with keeping updates current and with watching what your site does.
Deleting everything straight away. If you remove the way in without looking, you do not know what happened and you find out again a month later.
Cleaning files only. See point 8. The database belongs to it too, including triggers and scheduled jobs.
Running the check on a site that is already down. Then it does not work properly, because it needs WordPress to look at your administrators and your settings. First get the site to start again, then check.