Skip to content

The publication for web craftspeople Wednesday, 19 August 2026

Security

WordPress hardening: the minimal security baseline

Wordfence, Fail2ban and application passwords: three components, half a day, and nearly all automated attacks stop having any effect.

Hardening WordPress minimal : le socle sécurité que j'applique sur tous mes petits sites

On a small WordPress site, security is not a project: it is a baseline you lay down once, properly, and then stop thinking about. Three components, half a day of setup, and nearly all automated attacks stop having any effect. Here is that baseline, in deployment order.

Why a minimal baseline rather than a fortress

Most of what hits a small WordPress install is automated noise: bots requesting wp-login.php, scans for known vulnerabilities, attempts to enumerate users through the REST API. None of these attacks targets a specific site — they sweep the entire web. The baseline below cuts that volume. The rest — a targeted attack, a zero-day on a specific extension — cannot be handled with three lines of configuration, and practically never concerns a brochure site.

The best hardening is not the one that blocks everything: it is the one still in place and up to date six months later.

Component 1 — Wordfence, the application layer

Wordfence protects more than five million sites and its free version covers the essentials: application firewall, malware scanner comparing core files against the official repository, rate limiting, brute-force protection and two-factor authentication.

Known limitation: in the free version, new firewall rules arrive thirty days behind the paid version. The trade-off is acceptable on a brochure site; considerably less so on an active WooCommerce store.

Minimal settings after installation:

  • Switch the firewall to Extended Protection, which runs before PHP rather than as a plain plugin.
  • Enable two-factor authentication on every administrator account.
  • Enable user-enumeration blocking and hide the WordPress version.
  • Reduce email alerts to critical ones only: a constant notification stream eventually goes unread.

Component 2 — Fail2ban, the network layer

Wordfence acts at the PHP level. Fail2ban acts earlier, at server level: it reads the Nginx logs and bans the IP address at the system firewall as soon as an attack pattern repeats. The attacker then stops consuming PHP resources at all.

# /etc/fail2ban/filter.d/wp-login.conf
[Definition]
failregex = ^<HOST> -.*"POST /wp-login.php
            ^<HOST> -.*"POST /xmlrpc.php
ignoreregex =
# /etc/fail2ban/jail.d/wordpress.conf
[wp-login]
enabled  = true
filter   = wp-login
logpath  = /home/*/logs/nginx/access.log
port     = http,https
maxretry = 3
findtime = 3600
bantime  = 3600
Trap behind a proxy: if Nginx logs the proxy address rather than the visitor’s, Fail2ban will ban the proxy — and therefore every visitor. Restoring the real address (CF-Connecting-IP through the RealIP module) must be verified before the jail is armed.

The filter should always be tested before activation:

fail2ban-regex /home/mysite/logs/nginx/access.log 
  /etc/fail2ban/filter.d/wp-login.conf

Component 3 — Application passwords

Application passwords, native to WordPress, give a script, an integration or an automated routine a revocable credential distinct from the account’s main password. Each integration gets its own; revoking one affects none of the others.

Two operating rules follow: never reuse an application password across integrations, and check that no security extension disables them globally — Wordfence offers that setting, and enabling it silently cuts every REST integration on the site.

Zero-cost additions

MeasureEffect
Security headers (X-Content-Type-Options, Referrer-Policy, Permissions-Policy)Reduced browser-side attack surface
Disabling file editing in the adminPrevents code changes from a compromised account
Named administrator accounts, no “admin” userRemoves the default brute-force target
Encrypted backups stored off the production serverThe only measure that actually repairs after an incident

What to take away

Three components cover nearly all of the real risk on a small site: an application layer, a network layer and revocable credentials for integrations. Any additional measure should be judged on one question — will it still be maintained in six months?

This is the baseline I deploy on the thirty or so sites I self-host, behind CloudPanel and Cloudflare. The incident that cost me most was not an intrusion: it was the Wordfence setting that disables application passwords, which silently cut every one of my REST routines. — Simon Janvier

Also on Mail Studio

Read next