Title: WPS Protect: Login URL &amp; Security Headers
Author: Muhammad Junaid Tariq
Published: <strong>مئی 31, 2025</strong>
Last modified: اگست 15, 2026

---

Search plugins

![](https://ps.w.org/wps-protect-login-url-security-headers/assets/banner-772x250.
jpg?rev=3312453)

![](https://ps.w.org/wps-protect-login-url-security-headers/assets/icon-256x256.
png?rev=3304050)

# WPS Protect: Login URL & Security Headers

 By [Muhammad Junaid Tariq](https://profiles.wordpress.org/junaid434/)

[Download](https://downloads.wordpress.org/plugin/wps-protect-login-url-security-headers.2.0.0.zip)

 * [Details](https://bcc.wordpress.org/plugins/wps-protect-login-url-security-headers/#description)
 * [Reviews](https://bcc.wordpress.org/plugins/wps-protect-login-url-security-headers/#reviews)
 *  [Installation](https://bcc.wordpress.org/plugins/wps-protect-login-url-security-headers/#installation)
 * [Development](https://bcc.wordpress.org/plugins/wps-protect-login-url-security-headers/#developers)

 [Support](https://wordpress.org/support/plugin/wps-protect-login-url-security-headers/)

## Description

**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:

 1. A one-time rescue URL that works from any page on your site.
 2. `define( 'WPSP_DISABLE_LOGIN_GATE', true );` in `wp-config.php`.
 3. 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.

## Installation

 1. Upload the plugin files to `/wp-content/plugins/wps-protect-login-url-security-
    headers/`, or install through the Plugins screen.
 2. Activate the plugin.
 3. 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.

## FAQ

### 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 );` to `wp-config.php`, or run `wp wpsp 
login-url` over WP-CLI. Deactivating the plugin also restores `wp-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.

## Reviews

There are no reviews for this plugin.

## Contributors & Developers

“WPS Protect: Login URL & Security Headers” is open source software. The following
people have contributed to this plugin.

Contributors

 *   [ Muhammad Junaid Tariq ](https://profiles.wordpress.org/junaid434/)

[Translate “WPS Protect: Login URL & Security Headers” into your language.](https://translate.wordpress.org/projects/wp-plugins/wps-protect-login-url-security-headers)

### Interested in development?

[Browse the code](https://plugins.trac.wordpress.org/browser/wps-protect-login-url-security-headers/),
check out the [SVN repository](https://plugins.svn.wordpress.org/wps-protect-login-url-security-headers/),
or subscribe to the [development log](https://plugins.trac.wordpress.org/log/wps-protect-login-url-security-headers/)
by [RSS](https://plugins.trac.wordpress.org/log/wps-protect-login-url-security-headers/?limit=100&mode=stop_on_copy&format=rss).

## Changelog

#### 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.php` request 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 `Host` request header,
   allowing an open redirect, and issued it as a permanently cached `301`.
 * Requests were matched with an unanchored substring search, so any URL merely 
   containing `wp-admin` or `wp-login.php` — including ordinary posts and uploads—
   returned 404.
 * `exit` inside the `wp_logout` action 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 `429` with `Retry-
   After`. Covers the login form, XML-RPC, REST, Application Passwords, WooCommerce
   and BuddyPress.
 * Emergency access: one-time rescue URL, a `wp-config.php` constant, 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.php` with capability checks, nonce verification
   and a POST/Redirect/GET cycle, so refreshing no longer resubmits.
 * `X-XSS-Protection` now defaults to `0`, matching current OWASP guidance. The 
   previous `1; mode=block` enabled 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 `%i` identifier 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 across `wp-admin`
   is a separate, off-by-default option, because a restrictive Content-Security-
   Policy can interfere with the now always-iframed editor.
 * The `wpsplu_options` record, the `wpsplu` admin 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

## Meta

 *  Version **2.0.0**
 *  Last updated **2 months ago**
 *  Active installations **Fewer than 10**
 *  WordPress version ** 6.2 or higher **
 *  Tested up to **7.1.3**
 *  PHP version ** 7.2 or higher **
 *  Language
 * [English (US)](https://wordpress.org/plugins/wps-protect-login-url-security-headers/)
 * Tags
 * [Brute Force](https://bcc.wordpress.org/plugins/tags/brute-force/)[hide login](https://bcc.wordpress.org/plugins/tags/hide-login/)
   [login](https://bcc.wordpress.org/plugins/tags/login/)[security](https://bcc.wordpress.org/plugins/tags/security/)
   [Security Headers](https://bcc.wordpress.org/plugins/tags/security-headers/)
 *  [Advanced View](https://bcc.wordpress.org/plugins/wps-protect-login-url-security-headers/advanced/)

## Ratings

No reviews have been submitted yet.

[Your review](https://wordpress.org/support/plugin/wps-protect-login-url-security-headers/reviews/#new-post)

[See all reviews](https://wordpress.org/support/plugin/wps-protect-login-url-security-headers/reviews/)

## Contributors

 *   [ Muhammad Junaid Tariq ](https://profiles.wordpress.org/junaid434/)

## Support

Got something to say? Need help?

 [View support forum](https://wordpress.org/support/plugin/wps-protect-login-url-security-headers/)