Directory / plugin
WPS Protect: Login URL & Security Headers
v2.0.0 · by Muhammad Junaid Tariq
Move your login URL, stop brute-force attacks, and send HTTP security headers on every response. Lightweight, cache-friendly, no bloat.
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.phpto 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.phpand 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 );inwp-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.multicallis 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
429withRetry-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.