Title: Stoutwall – Security Hardening &amp; Login Protection
Author: felipepitol
Published: <strong>November 5, 2026</strong>
Last modified: November 6, 2026

---

Search plugins

![](https://ps.w.org/stoutwall/assets/banner-772x250.png?rev=3786847)

![](https://ps.w.org/stoutwall/assets/icon-256x256.png?rev=3786847)

# Stoutwall – Security Hardening & Login Protection

 By [felipepitol](https://profiles.wordpress.org/felipepitol/)

[Download](https://downloads.wordpress.org/plugin/stoutwall.1.3.0.zip)

 * [Details](https://wordpress.org/plugins/stoutwall/#description)
 * [Reviews](https://wordpress.org/plugins/stoutwall/#reviews)
 *  [Installation](https://wordpress.org/plugins/stoutwall/#installation)
 * [Development](https://wordpress.org/plugins/stoutwall/#developers)

 [Support](https://wordpress.org/support/plugin/stoutwall/)

## Description

Stoutwall applies well-known hardening measures that most sites should have, each
behind its own switch. There is no firewall, no scanner and no account to create:
it changes how WordPress behaves, and you can see and undo every change. One small
plugin instead of five single-purpose ones.

**What it can do**

 * **Limit login attempts** – after 5 failed logins in 15 minutes, the IP address
   is locked out for 15 minutes. Repeated lockouts last longer, up to 24 hours. 
   Works behind Cloudflare and other proxies, with a list of allowed IP addresses
   and ranges that are never locked out.
 * **Security headers** – sends `X-Content-Type-Options`, `X-Frame-Options` and `
   Referrer-Policy`, plus optional HSTS.
 * **Prevent code execution in uploads** – adds rules to `wp-content/uploads/.htaccess`
   that block PHP files, including `.phtml`, `.php5`, `.phar` and double extensions
   such as `image.php.jpg`. Rules from other plugins in the same file are kept.
 * **Disable XML-RPC** – turns off every XML-RPC method, including `pingback.ping`,
   which is often abused for DDoS amplification, and removes the `X-Pingback` header.
 * **Prevent user enumeration** – stops `?author=N` lookups and hides usernames 
   from the REST API for visitors, the users sitemap and oEmbed responses. Authors
   and editors keep the author list in the block editor.
 * **Generic login errors** – the login form no longer tells attackers whether a
   username exists. Registration errors are still shown.
 * **Disable application passwords** and **require login for the REST API** (both
   off by default).
 * **Disable file editors** – removes the theme and plugin file editors from the
   dashboard.
 * **Disable registration** – keeps “Anyone can register” off.
 * **Block the “admin” username** for new registrations.
 * **Hide username as display name** – users cannot save a profile whose public 
   display name is their login.
 * **Hide the WordPress version** from the page head and feeds.
 * **Remove the X-Powered-By header** that reveals the PHP version.
 * **Disable directory browsing** in the uploads folder.

**Check that it really works**

 * A **Check status** button confirms that each protection is in effect on your 
   server, for example that the `.htaccess` rules are present and the headers reach
   the browser, not only that the switch is on.
 * A read-only **security audit** looks for weak security keys, copies of `wp-config.
   php`, a public `debug.log`, an “admin” user, open registration with a powerful
   role and more. It also tests from outside whether PHP files in uploads run and
   whether folders can be listed. The quick checks also appear in **Tools  Site 
   Health**.

**Rules for your web server**

Stoutwall generates matching rules for **Apache, LiteSpeed, OpenLiteSpeed and Nginx**,
so the protections also cover static files and servers that ignore `.htaccess`. 
You review and paste them; nothing outside the uploads folder is changed for you.

**For developers and agencies**

 * WP-CLI: `wp stoutwall list|status|enable|disable|export|import|lockouts|unlock
   |allowlist|rules|audit`.
 * Export the settings to a JSON file and import them on other sites.
 * Filters such as `stoutwall_security_headers`, `stoutwall_public_rest_namespaces`,`
   stoutwall_login_max_failures` and `stoutwall_client_ip`.

**Privacy**

Stoutwall does not send anything to external servers, does not add cookies and does
not send emails. To limit login attempts it keeps, on your own site, a hashed IP
address of failed logins for 15 minutes and a partial IP address (such as 203.0.113.
x) of locked-out visitors for up to a day.

**Reporting security issues**

Please report vulnerabilities privately through the [Wordfence](https://www.wordfence.com/threat-intel/bug-bounty-program/)
or [Patchstack](https://patchstack.com/database/report) programs, which coordinate
the fix with the author before disclosure.

## Screenshots

[⌊Protections grouped by area, with a meter that shows how many are on.⌉⌊Protections
grouped by area, with a meter that shows how many are on.⌉[

Protections grouped by area, with a meter that shows how many are on.

[⌊The status check shows whether each protection is working.⌉⌊The status check shows
whether each protection is working.⌉[

The status check shows whether each protection is working.

## Installation

 1. Install Stoutwall from **Plugins  Add New**, or upload the `stoutwall` folder to`/
    wp-content/plugins/`.
 2. Activate the plugin. The protections that rarely cause problems start enabled.
 3. Go to **Settings  Stoutwall** to turn protections on or off, then click **Check
    status**.
 4. On Nginx or OpenLiteSpeed, open the **Server rules** tab and add the rules to your
    server.

## FAQ

### Does it work on Nginx and OpenLiteSpeed?

Most protections work on any server. Blocking PHP in uploads relies on `.htaccess`,
which Apache and LiteSpeed Enterprise read but Nginx and OpenLiteSpeed ignore. Open**
Settings  Stoutwall  Server rules**, pick your server and paste the rules it shows.
Then run the audit: it tests whether PHP in uploads is really blocked.

### I locked myself out. How do I get back in?

Wait for the lockout to end, or run `wp stoutwall unlock --all` with WP-CLI. To 
avoid it, add your office or VPN address under **Settings  Stoutwall  Tools  Allowed
IP addresses**. Without WP-CLI, rename the `wp-content/plugins/stoutwall` folder,
log in, rename it back and unlock the IP in **Settings  Stoutwall  Tools**.

### Everyone gets locked out at the same time

Your site is behind a proxy or CDN, so every visitor reaches WordPress with the 
same IP address. In the **Limit login attempts** row, open **Advanced** and choose
the header your proxy sets, for example Cloudflare.

### Will it break my site?

Each measure can be turned off on its own. Things to know before enabling them:

 * Disabling XML-RPC stops the Jetpack connection and the legacy WordPress mobile
   apps.
 * Security headers stop other sites from showing yours inside a frame. Turn them
   off if you need that.
 * HSTS makes browsers refuse plain HTTP for a year. Only turn it on when HTTPS 
   works on every page.
 * Requiring login for the REST API can break themes and plugins that load content
   through it. oEmbed, Contact Form 7, WooCommerce checkout and Jetpack stay public;
   use the `stoutwall_public_rest_namespaces` filter for others.
 * Disabling registration overrides the “Anyone can register” setting.
 * Blocking PHP in uploads affects any plugin that executes PHP files stored in 
   the uploads folder, which is rare and usually a red flag.

### What happens when I deactivate or delete the plugin?

Deactivating removes the plugin’s rules from the uploads `.htaccess` (other rules
stay) and every other measure stops applying. Deleting the plugin also removes its
settings.

### I used ProtectMyWordPress from GitHub. How do I move to Stoutwall?

Install and activate Stoutwall. It imports your ProtectMyWordPress settings and 
replaces its `.htaccess` rules. Then deactivate and delete ProtectMyWordPress.

## Reviews

There are no reviews for this plugin.

## Contributors & Developers

“Stoutwall – Security Hardening & Login Protection” is open source software. The
following people have contributed to this plugin.

Contributors

 *   [ felipepitol ](https://profiles.wordpress.org/felipepitol/)

[Translate “Stoutwall – Security Hardening & Login Protection” into your language.](https://translate.wordpress.org/projects/wp-plugins/stoutwall)

### Interested in development?

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

## Changelog

#### 1.3.0

 * New: limit login attempts, with longer lockouts for repeat offenders, a list 
   of locked-out IPs, allowed IPs and ranges, and support for Cloudflare and proxy
   headers.
 * New: security headers (X-Content-Type-Options, X-Frame-Options, Referrer-Policy)
   and optional HSTS.
 * New: switches to disable application passwords and to require login for the REST
   API (both off by default).
 * New: server rules for Apache, LiteSpeed, OpenLiteSpeed and Nginx, generated from
   the protections you have on.
 * New: read-only security audit with live tests for PHP in uploads and directory
   listing, also shown in Site Health.
 * New: WP-CLI commands and settings export/import.
 * The X-Powered-By header is now also removed from the login page and the dashboard.
 * Limit login attempts and security headers are turned on when you update. Turn
   them off in Settings  Stoutwall if you do not want them.

#### 1.2.1

 * The plugin link now points to the WordPress.org directory page.

#### 1.2.0

 * Renamed to Stoutwall for the WordPress.org Plugin Directory. Settings and `.htaccess`
   rules from ProtectMyWordPress are migrated on activation.
 * Uploads: rules are written in their own block even when `uploads/.htaccess` already
   exists. Before, an existing file meant no rules were added while the status still
   reported OK.
 * Uploads: rules work on Apache 2.2 and 2.4 and also cover `.phtml`, `.php5`, `.
   phar` and double extensions. They are removed on deactivation.
 * XML-RPC: pingbacks are now disabled too, and the `X-Pingback` header is removed.
 * User enumeration: also covers the users sitemap, oEmbed, POST requests and lists
   such as `?author=1,2`. The posts list filter in the dashboard and the block editor
   author list work again.
 * Generic login errors no longer hide registration errors.
 * “Hide username as display name” now checks profile updates. Before, it read a
   field that the registration form does not have, so it never applied.
 * The status check reports the state of each measure, translated, with clear labels.
 * All strings are in English and ready for translation.

#### 1.1

 * Fixed the settings form, the AJAX nonce and an XSS issue in notifications.
 * Options are sanitized on save and assets load only on the settings page.

#### 1.0

 * First release, as ProtectMyWordPress.

## Meta

 *  Version **1.3.0**
 *  Last updated **1 hour ago**
 *  Active installations **Fewer than 10**
 *  WordPress version ** 5.5 or higher **
 *  Tested up to **7.1.4**
 *  PHP version ** 7.4 or higher **
 * Tags
 * [hardening](https://wordpress.org/plugins/tags/hardening/)[limit login attempts](https://wordpress.org/plugins/tags/limit-login-attempts/)
   [security](https://wordpress.org/plugins/tags/security/)[Security Headers](https://wordpress.org/plugins/tags/security-headers/)
   [xml-rpc](https://wordpress.org/plugins/tags/xml-rpc/)
 *  [Advanced View](https://wordpress.org/plugins/stoutwall/advanced/)

## Ratings

No reviews have been submitted yet.

[Your review](https://wordpress.org/support/plugin/stoutwall/reviews/#new-post)

[See all reviews](https://wordpress.org/support/plugin/stoutwall/reviews/)

## Contributors

 *   [ felipepitol ](https://profiles.wordpress.org/felipepitol/)

## Support

Got something to say? Need help?

 [View support forum](https://wordpress.org/support/plugin/stoutwall/)