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.
- 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).
- 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.
- 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.
- Blocked common user enumeration vectors:
- 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
- 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)
- Privacy-first analytics
- Only analytics is self-hosted Plausible.
- No ad networks, no third-party marketing pixels, no selling/sharing of visitor data.
- 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.
- Removed jQuery Migrate
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.