WordPress Hosting Security Checklist

Scope Applies to any production WordPress site, with extra emphasis on agency hosting (multiple client sites on shared infrastructure). Operational detail for each item lives in wordpress-hardening. WordPress sites almost always process personal data — commenters, contact-form submissions, customer accounts. GDPR applies; treat the host as in-scope. 1. Pre-build VPS baseline complete. Work through the pre-launch VPS checklist before installing WordPress. Privacy decisions made. See privacy-by-design-server-build for the design-level questions — they apply to WordPress too. 2. Server-level isolation Per-site Unix user. Each client site owns its own user, group, document root. No shared www-data. NIS2: 21(2)(e); ISO 27001: A.5.15. Per-site PHP-FPM pool. Separate socket, separate open_basedir, separate worker limits. open_basedir scoped to the site’s root. Prevents cross-site filesystem access if one site is compromised. disable_functions configured. exec, passthru, shell_exec, system, proc_open, popen, parse_ini_file, show_source disabled at minimum. expose_php = Off. 3. Filesystem permissions Source code is not web-writable. PHP-FPM has read, no write on wp-includes, wp-admin, plugin and theme directories. NIS2: 21(2)(e); ISO 27001: A.8.4. wp-config.php mode 640, group nginx (or your web group). Never world-readable. PHP execution blocked under uploads/. Nginx deny all for \.php requests under the uploads tree. .git, .env, backups not in the document root. Verified by attempting to fetch them via HTTP. xmlrpc.php blocked. Unless a documented use case requires it; in which case IP-allowlist. 4. WordPress core configuration FORCE_SSL_ADMIN = true in wp-config.php. DISALLOW_FILE_EDIT = true. No theme/plugin editor in the dashboard. DISALLOW_FILE_MODS = true. Updates happen via wp-cli, not in-dashboard. FS_METHOD = 'direct'. Required when the web user cannot write source files. Authentication salts regenerated. Unique per install, rotated after any suspected compromise. NIS2: 21(2)(h); ISO 27001: A.8.24. XML-RPC disabled at the WordPress layer too. add_filter('xmlrpc_enabled', '__return_false');. 5. Database Dedicated database user per site. Not shared across sites. Least-privilege grants only. SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES. No global grants. NIS2: 21(2)(e); ISO 27001: A.5.15. Database baseline applied. See postgresql-hardening for Postgres, or apply equivalent MariaDB/MySQL hardening. TLS between WordPress and database. Mandatory across hosts. 6. Admin access No admin username. Removed at install; per-human admin accounts only. NIS2: 21(2)(i); ISO 27001: A.5.16. Strong password policy enforced. Minimum length, no common passwords. 2FA required for every admin account. Hardware key or TOTP preferred over SMS. NIS2: 21(2)(j); ISO 27001: A.8.5. Login rate limiting active. Nginx limit_req on wp-login.php (see nginx-ratelimit) plus a plugin like Limit Login Attempts Reloaded. /wp-admin IP-allowlisted where feasible. If client admins work from known networks. 7. Plugins and themes Source vetted. Every plugin from wordpress.org or a reputable vendor, updated within six months, not in a “closed” state. NIS2: 21(2)(d) (supply chain). Premium plugins licensed and current. No nulled / pirated copies — common compromise vector. Inactive plugins removed. Inactive ≠ uninstalled. Uninstall what is not in use. Update SLA documented. Security-flagged updates within 24 hours; routine updates within 7 days. NIS2: 21(2)(e),(g). No in-dashboard file editing. Enforced by DISALLOW_FILE_EDIT and by policy. 8. Backups Daily database backup + weekly content backup scheduled. Off-site, encrypted backup target. restic / borg to EEA region. GDPR: Article 32(1)(c). Backup retention matches the privacy policy. Cannot exceed stated user-data retention. GDPR: Article 5(1)(e). Backups not in the document root. Common misconfiguration — verify by HTTP. Restoration drill performed and timed. Quarterly minimum. 9. Logging and integrity Nginx access logs use a minimised log_format. Per the privacy-by-design guide. Login attempts logged and alerted on. wp core verify-checksums scheduled and alerting. NIS2: 21(2)(g); ISO 27001: A.8.16. wp plugin verify-checksums --all scheduled. 10. GDPR-specific items Privacy notice published and accurate. Reflects what is collected, including by plugins. Cookie consent implemented for any non-essential cookies. No pre-ticked boxes. GDPR: Article 7. Right to erasure tested. WordPress core supports it; verify every plugin storing personal data respects the request. Right to access tested. Data export produces a complete and readable file. Sub-processor list maintained. Every plugin or service that sends data off-site (analytics, email, payment, CRM). GDPR: Article 28. 11. Ongoing operation Update process documented. Who runs it, when, how out-of-hours updates are handled. Quarterly re-run of this checklist. Plugin drift, retention drift, and admin-account creep are the usual findings. External vulnerability scan run. WPScan or equivalent; results documented. Notes For agency hosting at scale, every item under “Server-level isolation” is non-negotiable. One compromised site can pivot to siblings within minutes if isolation is missing — and the compounding blast radius is exactly the failure mode regulators ask about first. ...

4 min