A personal note
I didn't set out to write a book. I set out to stop repeating myself.
Every time I set up a new WordPress site, hardened a server, or cleaned up after a compromise, I found myself going through the same steps, checking the same things, and explaining the same concepts to clients who had no idea how exposed their sites were. At some point it made more sense to write it all down properly than to keep reinventing it.
What you've just read comes out of years of real work, not from textbook theory or recycled blog posts. The setups I've described are ones I've actually run, on production sites ranging from personal blogs to corporate installations to multisite networks serving thousands of users.
I wrote this for the person who knows enough to be dangerous but wants to know enough to be confident. For freelancers offering their clients something more than a cheap hosting plan. For small business owners tired of finding out their site was compromised long after the fact. And for anyone who's googled "WordPress security" and drowned in contradictory advice.
I hope it's useful. I hope it's the thing you actually come back to.
If it has been, or if something's missing, or if something's wrong, let me know. [email protected].
Stu
Recommended resources
These are the tools, sites, and sources I'd point anyone to who wants to go deeper. No fluff, just the ones that are actually worth your time.
Vulnerability intelligence
- Wordfence Blog (
wordfence.com/blog) - The best source of WordPress specific threat intelligence. Detailed vulnerability disclosures, real world attack analysis, and security research. Subscribe to the email list. - Patchstack Weekly (
patchstack.com) - A weekly email summarising newly disclosed WordPress vulnerabilities. Essential reading if you manage multiple sites. The free tier also monitors your installed plugins. - WPScan Vulnerability Database (
wpscan.com/plugins) - Search any plugin or theme before you install it. Check your existing stack periodically. Free API tier covers most personal use cases. - NIST National Vulnerability Database (
nvd.nist.gov) - The authoritative CVE database. More technical than the WordPress specific sources but useful for looking up specific CVEs in detail.
General security
- Krebs on Security (
krebsonsecurity.com) - Brian Krebs covers the broader security landscape, including hosting, infrastructure, and web crime. Often relevant to WordPress site owners even when it's not specifically about WordPress. - Troy Hunt's Blog (
troyhunt.com) - Clear, practical writing on web security from the creator of Have I Been Pwned. Good for understanding the broader context of credential compromise and authentication security. - Have I Been Pwned (
haveibeenpwned.com) - Check whether your email addresses have appeared in known data breaches. Worth running your admin email addresses through this regularly.
WordPress administration
- WordPress Developer Documentation (
developer.wordpress.org) - The official source of truth for WordPress APIs, hooks, and core behaviour. Indispensable for anything beyond surface level configuration. - WP-CLI Documentation (
wp-cli.org) - Full reference for every WP-CLI command. If you're doing server level WordPress management, this should be open in a tab. - WordPress Hardening Guide (
wordpress.org/support/article/hardening-wordpress) - The official WordPress hardening documentation. Worth reading alongside this book as a cross reference.
Server and infrastructure
- DigitalOcean Tutorials (
digitalocean.com/community/tutorials) - Some of the best server configuration tutorials available. Nginx, MySQL, PHP-FPM, UFW, Let's Encrypt. Well written and kept reasonably up to date. - Mozilla SSL Configuration Generator (
ssl-config.mozilla.org) - Generates recommended Nginx and Apache SSL configurations based on your server and software versions. Takes the guesswork out of TLS configuration. - SSL Labs Server Test (
ssllabs.com/ssltest) - Test your SSL configuration against current best practices. Aim for A or A+. - Security Headers (
securityheaders.com) - Test your HTTP security headers and get specific recommendations for what's missing or misconfigured.
If your site gets hacked
This is the condensed version. If you're in the middle of a crisis, work through this in order.
Immediate steps
- Don't panic - A hacked site is recoverable. Take a breath and work methodically.
- Stop it executing PHP - Not maintenance mode. Maintenance mode is still WordPress running, and if the malicious code loads alongside WordPress, a maintenance page serves it just as faithfully as a real one. Stop the web server, or firewall the site down to your own IP, so nothing runs while you work. If several sites share a hosting account, stop all of them. Chapter 11 explains why this is the step that decides whether the cleanup sticks.
- Change all passwords immediately - WordPress admin accounts, FTP, hosting control panel, database user. Do this before anything else. If the attacker still has valid credentials, everything else you do can be undone.
- Regenerate WordPress security keys and salts - This invalidates all active sessions including any the attacker may have open. Do this in
wp-config.phpor via the official generator atapi.wordpress.org/secret-key/1.1/salt/. - Preserve evidence - Before restoring, capture the current state. Download your access logs, error logs, and a snapshot of the current files. You'll need these to understand how the compromise happened.
Investigation
-
Check for new admin accounts - Look in WordPress users for accounts you don't recognise. Delete any that shouldn't be there, but document them first.
-
Check for modified files - Use Wordfence's file integrity scanner or run a manual find for recently modified PHP files:
find /var/www/html -name "*.php" -newer /var/www/html/wp-config.php -type f -
Check the uploads directory - Look for PHP files that have no business being there:
find /var/www/html/wp-content/uploads -name "*.php" -type f -
Review your access logs - Look for POST requests to unusual locations, requests from unfamiliar IPs, or spikes in traffic that correlate with when the compromise occurred.
-
Identify the entry point - Before restoring, understand how they got in. Common vectors include a vulnerable plugin, a compromised password, or a misconfigured file permission. If you don't close the door before restoring, you'll be compromised again.
Recovery
- Identify a clean backup - Go back through your backup history and find a backup taken before the compromise occurred. Use your logs and file modification times to help narrow down the timeline.
- Restore to a clean environment - Ideally restore to a fresh server or document root. Don't restore on top of compromised files without first removing everything.
- Update everything - Before going back online, update WordPress core, all plugins, and all themes to their latest versions. Apply any security patches that were pending.
- Harden and audit - Run through the security checklist from Chapter 12. Fix anything that's missing. This is also a good time to implement anything from this book you hadn't gotten around to yet.
- Relaunch and monitor closely - Bring the site back online and watch it carefully for the next 24 to 48 hours. Review Wordfence logs, server logs, and uptime monitoring.
After the crisis
- Notify anyone who needs to know - If the site collected user data and that data may have been exposed, you may have legal notification obligations depending on your jurisdiction and the nature of the data. Take this seriously.
- Write a post mortem - Even a brief one. What happened, how it happened, what you did, and what you'll do differently. The sites that get compromised twice are usually the ones where no one took the time to understand the first compromise properly.
- Review your backup and monitoring setup - A compromise is uncomfortable but also an opportunity to close gaps. Did your monitoring catch it? Did your backups work? If not, fix that now while the motivation is fresh.
Changelog
This book is updated regularly. The most recent changes are listed here.
October 2026 - PHP2Shell, stolen management keys and a poisoned Pro release
- Chapter 1: the 21 October PHP flaws (CVE-2026-109618 and CVE-2026-109619) as the worked example for PHP support windows; PHP-FPM over
mod_php; how to tell a backported distribution package is patched;post_max_sizebrought down from 64M to 32M;session.upload_progress.enabledandregister_argc_argvadded to the settings list - Chapter 2: the three 7.1 security releases in nineteen days, and CVE-2026-87902 as the current example of why point releases are not optional
- Chapter 8: a fourth shape of supply-chain attack, stolen remote management keys (UpdraftCentral, 18 and 19 October); Rank Math PRO 3.0.123 added to the second; keys and connections added to the inventory; the WordPress.org cooldown noted as not covering vendor-hosted premium updates
- Chapter 1: where Nginx comes from (distribution backports versus nginx.org) and how to read an nginx advisory against your own configuration
- Chapter 6: Let's Encrypt's move to 64-day certificates from February 2027, ACME Renewal Information and the stale Certbot in Ubuntu's archive, and why Certbot's TLS snippet sidestepped the October nginx session forgery bug
- Chapters 11, 12 and 13: revoke management keys as part of recovery, why a cookie-setting backdoor makes 2FA irrelevant until the code is gone, restore from before the advisory date when persistence is spread across core, options, cron and
mu-plugins, and a monthly review of connections and of accounts whose capabilities do not match their role
September 2026 - WordPress 7.1 follow-up
- Chapter 14: the WordPress 7.1 Abilities API filters that can bypass or override an ability's permission check, how to find plugins that hook them, and
wp_ability_invokedas the audit-log hook that sees short-circuited calls - Chapter 8: EssentialPlugin timeline corrected (the backdoor shipped dormant in August 2025 and was switched on in April 2026); the OptinMonster CDN attack added as the third supply-chain shape; WordPress 7.1 and WP Rocket as the current staging example
- Chapter 1: client-side media processing in 7.1 and what it does and does not do for the Imagick attack surface
- Chapters 11 and 12: re-enrol 2FA after a compromise, because the ShapedPlugin payload harvested TOTP seeds
- Chapter 2: 7.0.2 as a forced update and why majors stay manual
September 2026 - Persistence, hashing and depth pass
- Redis and Valkey exposure added to Chapter 9: bind to loopback, protected-mode, and why an open instance is a remote code execution path that survives a file cleanup
- OPcache poisoning added to Chapter 9:
validate_timestamps=0as a persistence mechanism and why a cleanup must flush the cache - bcrypt (WordPress 6.8) and the value of a stolen
wp_userstable added to Chapter 3; scheduled 90-day password expiry dropped in favour of rotate-on-evidence, per current NIST guidance - Plugin auto-update rollback (WordPress 6.3) noted in Chapter 8
.gitin the webroot added to Chapter 12's deployment section- Chapter 5 prefix-change corrected (references, not table names; no multisite
--networkflag) and Chapter 7 robots.txt no longer blocks plugin and theme assets
September 2026 - Email authentication and phishing
- SPF, DKIM and DMARC added to Chapter 2's email section, with the records to publish and the order to roll them out
- New phishing section in Chapter 3: the lures aimed at WordPress admins (fake update notices, fake host infection emails, admin-email changes) and why passkeys are the structural fix
September 2026 - Chapter 14 rewrite
- Chapter 14 rewritten with runnable detail: the
wp abilitycommands and REST endpoints for auditing what is exposed to MCP, the real provider-key constant names the Connectors API reads, and a concrete way to disable the adapter - New section on prompt injection: how attacker-written content (comments, reviews, form submissions) can steer an agent, why the capability check does not catch it, and the least-privilege and read-only defences that do
September 2026 - Currency pass
- Protect The Shire cooldown corrected to six hours, and the automated release review that now blocks bad releases added to Chapters 8 and 12
- Patchstack's 2026 figures on vulnerability volume and time to exploitation added to Chapter 8
- Elementor Pro's exploited file-upload flaw added to Chapter 2 as the worked example for blocking PHP in uploads
- WordPress 7.1 and the September core security initiative noted in Chapter 2
- Apache examples moved to 2.4
Requiresyntax throughout; the 2.2Orderform fails silently on current servers wp-config.phppermissions made consistent at440across every chapter- The crisis runbook now matches Chapter 11 on stopping PHP rather than using maintenance mode
- PHP and Ubuntu support windows restated as fixed dates
August 2026 - WordPress 7.0 and the AI agent stack
- New Chapter 14 on AI agents and the MCP attack surface introduced in WordPress 7.0
- Updated the hosting chapter for current PHP support and the Imagick/Ghostscript RCE class
- Expanded the Application Passwords guidance now that agents authenticate with them
- Added coverage of the plugin update cooldown ("Protect The Shire") to the plugin and maintenance chapters
- Added a print-quality PDF edition, included with every purchase and downloadable from the reader. The web reader remains the canonical, continuously updated version; the PDF is a dated snapshot of it
May 2026 - Hardening additions
- Expanded coverage of file and information leaks at the server level
- Added a working example for restricting origin traffic to Cloudflare's IP ranges
- New guidance on auditing the must-use plugins folder for unauthorised files
April 2026 - Initial release
- All 13 chapters published
- Foreword, disclaimer, and outro added
- Covers WordPress 6.x, PHP 8.3 and 8.4, current plugin landscape as of April 2026
Protect My WP is a living document. Check back for updates, or follow along at protectmywp.com.
If something's wrong, missing, or could be better, [email protected].