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.
...