Descriere
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.
Instalare
- Upload the plugin files to
/wp-content/plugins/wps-protect-login-url-security-headers/, or install through the Plugins screen. - Activate the plugin.
- Go to WPS Protect in the dashboard menu.
Activation does not change your login URL. Nothing moves until you set a slug yourself, and the plugin issues a rescue URL at that moment.
Întrebări frecvente
-
What happens if I forget my login URL?
-
Use the rescue URL shown when you saved the slug. If you no longer have it, add
define( 'WPSP_DISABLE_LOGIN_GATE', true );towp-config.php, or runwp wpsp login-urlover WP-CLI. Deactivating the plugin also restoreswp-login.php, and your settings survive deactivation. -
Will this break my caching plugin?
-
Login and REST requests are never cached, so brute-force protection and the login gate are unaffected. Security headers are sent by PHP, so on a page served from a full-page cache they may be served by your cache layer instead. If your host serves cached pages without invoking PHP, set the headers at the server level too.
-
Does it work behind Cloudflare?
-
Yes, but configure your proxy ranges under the brute-force settings first. Until you do, the plugin deliberately declines to block by IP address rather than risk locking out every visitor sharing a proxy address.
-
Will it conflict with another security plugin?
-
Enable „do not overwrite headers already set” if something else is already sending headers. Running two plugins that both hide the login URL is not supported — pick one.
-
I upgraded from 1.x. What changed for me?
-
Your settings are migrated automatically, including your login slug, HTTPS setting and any header values you saved. One thing intentionally does not carry over: 1.x applied a hard-coded
Content-Security-Policy: default-src 'self'whenever you had not set one, which blocked inline scripts and styles on most sites. That fallback is gone. If you want a CSP, set one explicitly on the Security Headers tab.
Recenzii
Nu există nicio verificare pentru acest modul.
Contributori și dezvoltatori
„WPS Protect: Login URL & Security Headers” este un software open-source. La acest modul au contribuit următoarele persoane.
ContributoriTradu „WPS Protect: Login URL & Security Headers” în limba ta.
Te interesează dezvoltarea?
Răsfoiește codul, vezi depozitarul SVN, sau abonează-te la jurnalul de dezvoltare prin RSS.
Istoric modificări
2.0.0
Complete architectural rewrite, plus WordPress 7.1 compatibility.
Fixed (critical)
- Administrators were locked out of
/wp-admin/whenever a custom login URL was set. The capability check that guarded the dashboard was inverted: signed-in administrators were blocked while lower-privileged users were let through. - Every
admin-ajax.phprequest returned 404 with a custom login URL set, breaking the block editor, media uploads, WooCommerce and any plugin using AJAX. - The default
Content-Security-Policy: default-src 'self'was applied to every site that had not visited the settings screen, blocking inline scripts and styles used by WordPress core, most themes and most plugins. Access-Control-Allow-Origin: *is no longer sent by default.- The HTTPS redirect built its target from the unvalidated
Hostrequest header, allowing an open redirect, and issued it as a permanently cached301. - Requests were matched with an unanchored substring search, so any URL merely containing
wp-adminorwp-login.php— including ordinary posts and uploads — returned 404. exitinside thewp_logoutaction aborted password resets and any programmatic logout.- Password-protected posts (
action=postpass) no longer return 404. - Settings are no longer deleted when the plugin is deactivated. Deletion now happens on uninstall, as it should.
Added
- Brute-force protection: escalating lockouts, per-IP and per-username tracking, allowlist and blocklist, honeypot, generic error messages, and
429withRetry-After. Covers the login form, XML-RPC, REST, Application Passwords, WooCommerce and BuddyPress. - Emergency access: one-time rescue URL, a
wp-config.phpconstant, and WP-CLI commands. - Login slug validation against reserved paths, existing content and post-type archives.
- Security headers now apply to the login screen, dashboard and REST API, not only the front end.
- Content-Security-Policy-Report-Only, Cross-Origin-Opener-Policy, Cross-Origin-Resource-Policy and X-Permitted-Cross-Domain-Policies.
- Header value validation that rejects response splitting, with advisory warnings for risky values.
- Proxy-aware client IP resolution with configurable trusted ranges, and proxy-aware HTTPS detection.
- WP-CLI:
wp wpsp login-url,set-slug,disable-gate,rescue,unlock,lockouts,audit. - Audit log with retention policy and an IP anonymisation option.
Changed
- Rewritten as PSR-4 classes under
src/, separated into Login, Headers, SSL, Brute-force, Admin, Support, CLI and Compat modules. - Settings are saved through
admin-post.phpwith capability checks, nonce verification and a POST/Redirect/GET cycle, so refreshing no longer resubmits. X-XSS-Protectionnow defaults to0, matching current OWASP guidance. The previous1; mode=blockenabled a deprecated browser filter with vulnerabilities of its own.- HSTS requires an explicit confirmation and a secure connection before it is sent.
- Minimum requirements raised to WordPress 6.2 and PHP 7.2. WordPress 6.2 is required for the
%iidentifier placeholder in$wpdb->prepare(), which the brute-force log uses to quote table names.
Compatibility
- Tested against WordPress 7.1. The plugin ships no JavaScript or CSS, so the 7.1 iframed editor,
@wordpress/components, jQuery UI 1.14.2 and client-side media processing changes do not apply to it. Applying security headers acrosswp-adminis a separate, off-by-default option, because a restrictive Content-Security-Policy can interfere with the now always-iframed editor. - The
wpsplu_optionsrecord, thewpspluadmin page slug and its tab URLs are all preserved. Removed 1.x functions remain declared as no-op shims that raise a deprecation notice rather than a fatal error.
1.1
- Added Permissions-Policy header support
- Improved Content-Security-Policy configuration
- Enhanced login URL handling
- Added tab-based admin interface
- Updated security headers with recommended values
1.0
- Initial release with basic security features
