Blog
Auditing WordPress? Start With Your Plugins
Stop auditing WordPress core and start auditing your plugins: a practical, plugin-first security audit for small teams.
Summary
Most WordPress security audits are backwards: they emphasize core updates and scanner reports while the vulnerabilities that actually bite live in plugins. A SANS white paper found over 96% of ecosystem vulnerabilities originate in third-party plugins, and roughly 43% need no authentication. This article walks through a plugin-first audit for a small in-house marketing team, using the story of a site that got hacked because everyone was scanning the wrong layer. You'll learn to inventory and classify every plugin, test unauthenticated attack surfaces, manually review users and logs, and translate findings into a risk language a non-technical boss understands. The result is a quarterly triage ritual instead of a checkbox exercise.
Most WordPress security audits are theater. You spend an afternoon updating core, changing the admin password, and running a plugin scanner that proudly reports "No critical issues." Meanwhile, the plugin that accepted file uploads and was last updated three years ago sits quietly in your uploads directory, waiting for someone who isn't on the guest list.
The numbers back this up. A SANS white paper on scanning WordPress plugins found that more than 96% of vulnerabilities in the WordPress ecosystem originate in third-party plugins, with themes at 4% and core under 1%. Roughly 43% of those flaws can be exploited without any authentication. So when your audit spends most of its energy on core, you are examining the trees while a forest fire starts in the plugin directory next door.
This isn't a call to panic about core. Core vulnerabilities like the wp2shell RCE flaws that got public exploits recently should be patched the day they're announced. But they are rare enough that they don't deserve the bulk of your audit hours. The bulk belongs to plugins, and that's where the real workflow begins.
Picture the before scenario: a Sunday morning, your site redirects to a casino page, and your boss emails, "I thought we had security." You did have security — you had a checkbox audit. The after scenario is a triage system that treats plugins as the attack surface they actually are, tests them from the outside, and checks the things scanners can't see.
You're on a small marketing team with a WordPress site that's been running since 2017. It has a custom event-registration plugin a freelancer built in 2019, a contact form plugin with a file upload field, and a slider plugin that was sold and no longer has a public updates page. This is not an unusual stack. This is where your audit starts.
The plugin inventory is your security policy
Take inventory of every plugin and theme. Write down the version, the last update date, whether the vendor is still alive, and whether anyone actually uses it. Then classify each one into a bucket: maintained and used, maintained and unused, abandoned but used, abandoned and unused. Remove the unused ones immediately. Ignore the "it's only $50/month" defense — an unused plugin is a liability, not a feature. For the abandoned-but-used ones, decide: replace it, or accept the risk and write it down in a risk register your boss has seen.
The event-registration plugin falls in the abandoned-but-used bucket. It takes payments and sends confirmation emails, and replacing it is a project, so you keep it for now. But you write a note that says, "this is the most likely source of a future breach," and you add it to the top of the test list.
| Attack surface | Share of WordPress known vulnerabilities | Audit priority |
|---|---|---|
| Third-party plugins | Over 96% | Highest — inventory, scan, test, replace |
| Themes | About 4% | Medium — only if custom or outdated |
| WordPress core | Under 1% | Low — keep patched, move on |
When SecurityWeek counted more than 8,000 new WordPress vulnerabilities in 2024, the vast majority were of this type: plugin issues, not core patches. A scanner will tell you about the ones that have been disclosed and given a CVE. It will not tell you about the custom freelancer code with no CVE, because nobody has ever looked at it carefully. That manual look is your job. For a deeper walkthrough of plugin-specific checks, see this guide to auditing your WordPress plugins for vulnerabilities.
Test it like a stranger: the 43% that need no password
Your scanner has already told you nothing is wrong. Now do what it can't: probe the site from the outside, with no login. Start with every file upload field, every form that processes a POST, every admin-ajax endpoint. Does the upload actually check the file content, or only the extension? Where do the uploaded files land, and can the web server execute PHP in that directory? The 43% of plugin flaws that require no authentication usually sit in exactly these places: unauthenticated stored XSS, arbitrary file upload, and PHP object injection.
The contact form plugin lets visitors attach a resume. It renames the file using the visitor's original filename, so you upload "resume.php" and it saves it in a /uploads/contact/ folder that is writable by design. If the server also allows running PHP in that directory, the attacker just got a webshell. Fastly has documented active exploitation of unauthenticated stored XSS in WordPress plugins — this is not a niche slide-deck risk. Your test is simple: create a file with known content, upload it, and see if it comes back with its original name and type. Then try uploading a .php file. If it comes back as .php, you've just found an exploitable hole.
This is also where the "but our security plugin has a WAF" argument breaks down. A WAF can block a known payload, but the path-normalization rules it relies on often diverge from what the server actually does. The OWASP Web Security Testing Guide is a better reference than any dashboard: it describes how to test for file upload flaws and stored XSS in a methodical way. And if you discover the plugin is abandoned, it's time to apply the cleanup protocol: the hidden danger of abandoned WordPress plugins explains why leaving a dead extension in place is worse than removing it and adjusting your workflow.
What the scanner can't see: users, logs, and old code
Dynamic tests catch what's exposed right now. The manual review catches what's already inside. Start with user accounts: open the admin list and look for accounts you didn't create. An admin named "support" with a free-mail address and no human behind it is a backdoor, not a colleague. Check file timestamps in wp-content/uploads for anything recently modified that isn't your content. Check the server access log for requests that look like a bot's curl command rather than a person's browser.
The event plugin has a "speaker photo" upload that saves into uploads/event-headshots/. During the test you find a file that isn't one of yours — a small PHP file with a random-looking name. That's your webshell. It got there through the same upload flaw you tested two weeks ago, and by now a scanner still wouldn't "see" it because it's not a plugin vulnerability; it's evidence of one. The manual review finds it, deletes it, and checks the log for the IP address that put it there. Invicti has noted that PHP object injection in plugins is on the rise, and it's nearly invisible to black-box scans because the malicious object only materializes during execution. The only way to spot it is to read code for dangerous patterns like calling unserialize() on user-supplied input. Reading a few hundred lines of the custom plugin is cheaper than paying an incident-response retainer.
This is also where the standard advice to "just install more security plugins" reaches its limit. Stacking three security plugins gives you overlapping WAF rules that block each other, a torrent of duplicate log emails, and the occasional "you are banned" error on your own admin login. One active security plugin, configured well, is enough. Read about why too many security plugins backfire before adding anything else to the pile.
Telling your boss the truth without setting off panic
Your boss doesn't care about CVSS scores or PHP object injection. He cares about the site going down, the store not taking orders, and the IT budget. The translation is simple: "This plugin has a known unauthenticated remote code execution flaw. A stranger can delete our site content or install a backdoor. We need to replace it this quarter." Then show the priority list: replace the event plugin, disable the contact form's file upload until it properly validates file types, rotate all admin credentials, and schedule the next quarterly review.
You also have a language advantage: CISA maintains the Known Exploited Vulnerabilities catalog, which tells you exactly which published flaws are being actively used in the wild. If any of your plugins appear there, the argument is no longer theoretical — a known exploit exists, and you're on the clock. If they don't, use it anyway as a standard for what "urgent" means. CISA's tracking makes it easier to convince a non-technical boss that this is not a phishing email; it's a public database of what attackers are doing right now. When the quarter ends, you'll have a remediation workflow, not a one-time checkbox exercise. A workflow for turning vulnerabilities into a patch cycle keeps the habit alive.
The before was a broken site, a frantic email, and a clean scanner report that said nothing was wrong. The after is a quarterly ritual: inventory, classify, test from the outside, review users and logs, and write down the decisions you made and the risks you accepted. The scanner becomes a map of where to look, not a certificate of health. The plugins become a list you know by name. And the next time your boss asks about the audit, you'll have an answer that doesn't involve crossing your fingers.
