Security hardening for WordPress

This is a running log of the security hardening I’ve applied to this WordPress install. The goal: reduce attack surface, keep admin access tight, and keep the site fast + stable.

  1. Strong authentication
    • Enabled 2FA for admin access. (Two Factor by WordPress)
    • Enabled passkey/WebAuthn login for stronger phishing-resistant auth. (WebAuthn Provider for Two Factor by Volodymyr Kolesnykov)
    • Disabled WordPress comments entirely (no comment endpoints or spam surface).
  2. Cloudflare edge protection (Tunnel + Access)
    • Site is served through Cloudflare Tunnel (origin not directly exposed).
    • Restricted backend access using Cloudflare Access:
      • /wp-admin* and /wp-login.php* require authentication.
    • Public site stays public.
  3. WordPress attack surface reduction
    • Blocked common user enumeration vectors:
      • /?author=1 style enumeration blocked.
    • Author archives redirected away (no public author pages).
    • REST user endpoints blocked for anonymous users (prevents username scraping) while keeping Elementor/editor working for logged-in users.
    • XML-RPC disabled (and optionally blocked at the edge):
    • Removes an old remote-auth surface and pingback abuse vector.
  4. Security headers (Cloudflare Response Header Transform Rule)
    • Set at the edge so they apply consistently and don’t depend on the container/webserver.
    • Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
    • X-Content-Type-Options: nosniff
    • X-Frame-Options: SAMEORIGIN
    • Referrer-Policy: strict-origin-when-cross-origin
    • Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=(), usb=()
    • Cross-Origin-Opener-Policy: same-origin
  5. CSP (Content Security Policy)
    • Started in Report-Only mode to avoid breaking Elementor, then tightened.
    • Current CSP allows:
      • self-hosted assets
      • inline styles/scripts needed for Elementor
      • blob: workers (Elementor can spawn workers from blob URLs)
      • Plausible analytics endpoint/script
    • Example structure (high-level):
      • default-src ‘self’ https:
      • script-src ‘self’ https: ‘unsafe-inline’ …
      • style-src ‘self’ https: ‘unsafe-inline’
      • worker-src ‘self’ blob:
      • connect-src ‘self’ https: … (includes Plausible)
  6. Privacy-first analytics
    • Only analytics is self-hosted Plausible.
    • No ad networks, no third-party marketing pixels, no selling/sharing of visitor data.
  7. Performance-related hardening
    • Removed jQuery Migrate
      • Reduced attack surface + less JS
    • Deferred non-critical custom scripts
      • Theme toggle, code copy
    • Reduced unnecessary WP features
      • Disabled wp-emoji, XML-RPC, commenting functionalities etc.

Checklist for future me

  • Keep WP core/plugins/themes updated.
  • Periodically re-run security header + CSP checks (curl -I + DevTools).
  • Re-verify Cloudflare Access rules after any domain/routing changes.
  • Maintain backups + verify restoring works.