About this plugin
WPS Protect combines the three defences most WordPress sites install three separate plugins for — a hidden login URL, brute-force rate limiting, and HTTP security headers — into one lightweight plugin with no upsells and no performance overhead.
Login URL protection
- Move wp-login.php to a slug of your choice.
- Choose what the old login URL returns: a 404, your home page, a custom URL, or a plain message.
- Slugs are validated before they are saved, against reserved WordPress paths, existing pages and post-type archives, so you cannot make your own content unreachable.
- Signed-out visitors to /wp-admin/ are sent to your login page with their destination preserved, instead of hitting a dead end.
- AJAX, admin-post.php and REST endpoints stay reachable, so front-end forms, carts and the block editor keep working.
- Password-protected posts, logout links, and password-reset emails all continue to work.
Emergency access
Losing your login URL should never mean editing the database. Three independent recovery routes:
- A one-time rescue URL that works from any page on your site.
- define( 'WPSP_DISABLE_LOGIN_GATE', true ); in wp-config.php.
- WP-CLI: wp wpsp login-url, wp wpsp set-slug, wp wpsp disable-gate.
The site administrator is emailed whenever the rescue URL is used.
Brute-force protection
- Escalating lockouts — the second offence lasts longer than the first.
- Tracks attempts per IP address and per username, so a distributed attack on one account is still caught.
- Covers every way WordPress checks a password: the login form, XML-RPC, the REST API, Application Passwords, WooCommerce and BuddyPress.
- system.multicall is disabled, closing the XML-RPC amplification trick that turns one request into hundreds of password guesses.
- Requests to your old login URL count as attacks — nothing legitimate knows that address any more.
- Proxy-aware: forwarding headers are trusted only from proxy ranges you configure, so nobody can spoof a header to dodge the limiter or get themselves allowlisted.
- Optional honeypot field, and generic error messages so the login and lost-password forms stop confirming which accounts exist.
- Locked-out requests return 429 with Retry-After, so Cloudflare, Fastly or fail2ban can shed the attack at the edge.
Security headers
- X-Frame-Options, X-Content-Type-Options, Referrer-Policy, X-XSS-Protection, X-Permitted-Cross-Domain-Policies, Strict-Transport-Security, Content-Security-Policy (including Report-Only), Permissions-Policy, Cross-Origin-Opener-Policy, Cross-Origin-Resource-Policy and CORS.
- Headers are sent on the front end, the login screen, the dashboard and REST responses — not just the front end.
- Safe defaults: only headers that suit essentially every site are on out of the box. CSP, HSTS, Permissions-Policy and CORS ship switched off with a recommended value pre-filled, because guessing those breaks real sites.
- Every value is validated against header injection before it is saved, and risky settings are flagged with an explanation rather than silently accepted.
- HSTS is only sent over a secure connection and only after you confirm your subdomains are ready.
HTTPS enforcement
- Redirects insecure requests, honouring forwarding headers from trusted proxies so sites behind Cloudflare or a load balancer do not loop.
- Form submissions redirect with 307, so no data is lost.
- Cannot be switched on from an insecure dashboard session, which is the usual way people lock themselves out.