Modern WordPress attacks don’t just target your login page—they probe XML-RPC, brute-force APIs, enumerate plugins, scan theme directories, drop PHP shells into /wp-content/, and hit known backdoor filenames like style.php.
A secure WordPress deployment in 2025 requires a layered, defense-in-depth architecture where each system blocks threats at the level where it is most effective.
This guide covers the full stack I use in production:
- Really Simple Security
- Wordfence
- Cloudflare Proxying, Turnstile, and WAF
- pfSense firewall Cloudflare-origin lock
- HAProxy external + internal frontends
- ACL-based exploit blocking
- Origin-level .htaccess fixes
- OSI-layer mapping of all components
Hardening WordPress with Really Simple Security and Wordfence
The first place many people begin their hardening is the WordPress application layer. This reduces login-based attacks, plugin abuse, and malicious modifications.
Really Simple Security
Really Simple Security (RSS) hardens authentication, login workflows, and file protection.
Recommended Settings
- Disable or restrict XML-RPC
- Enable Two-Factor Authentication
- Enforce strong passwords
- Enable HTTPS
Why RSS Matters
RSS blocks many login-targeted attacks at the application layer and greatly strengthens WordPress’ authentication model.
Wordfence
Wordfence provides deep local protection, file integrity monitoring, and malware scanning.
Recommended Settings
- Enable Firewall
- Use aggressive brute-force lockouts
- Enable File Integrity Scans
- Limit Live Traffic
- Block user enumeration
Why Wordfence Still Matters
Even with Cloudflare and HAProxy filtering traffic, Wordfence is essential because it:
- Detects malicious/infected plugins
- Identifies modified PHP files
- Finds uploaded shells
- Flags internal changes
- Shows blocked or suspicious access attempts WordPress actually receives
- Provides an audit log of blocked malicious attempts that can be analyzed to add additional protection rules upstream
Hardening with Cloudflare Proxying and WAF
On the flip side, Cloudflare acts as the first line of defense, blocking malicious traffic globally before it ever reaches your network.
Cloudflare offloads:
- Malicious IP filtering
- Bot detection
- URL normalization
- DDoS absorption
- TLS termination
- Path-based WAF filtering
- Turnstile verification for forms such as login page
This alone usually reduces origin load by 80–95%.
Recommended Cloudflare Settings
- Enable proxying to hide your external IP (orange cloud)
- Enable WordPress/PHP Managed Rules
- Security Level: High
- Enable URL Normalization
- Enable Brotli, HTTP/2, HTTP/3
- Browser Cache TTL ≥ 1 month
- Use Cloudflare Turnstile on login
- Bot Fight Mode (Light)
Cloudflare Firewall Rule for WordPress Hardening
This rule blocks the high-risk WordPress paths most commonly abused by bots, scanners, and exploit kits.
Create it under:
Security → Security Rules → Create Rule → Custom Rule
Action: Block
Placement: First
Cloudflare Expression
(http.request.uri.path contains "/wp-login.php") or (http.request.uri.path contains "/xmlrpc.php") or (http.request.uri.path contains "/wp-admin") or (http.request.uri.path contains "/wp-json/litespeed") or (http.request.uri.path contains "alfacgiapi") or (starts_with(http.request.uri.path, "/plugins/")) or (http.request.uri.path contains "/style.php") or (http.request.uri.path contains "/wp-content/" and ends_with(http.request.uri.path, ".php"))Why These Paths Are Blocked
| Path | Why Attackers Target It | What This Blocks |
| /wp-login.php | Main brute-force target | Credential stuffing, password spraying |
| /xmlrpc.php | Allows amplified login attempts | XML-RPC authentication floods |
| /wp-admin | Enumeration and probing | Admin scans, exploit discovery |
| /wp-json/litespeed | Known LSCache exploit | REST exploit payloads |
| alfacgiapi | Non-WP execution directory | Cross-CMS exploit probes |
| /plugins/ | CMS-wide plugin scanners | Automated exploitation scans |
| /style.php | Malware backdoor filename | Remote execution attempts |
| /wp-content/*.php | Uploaded shells | Execution of malicious files |
These rules were in large part chosen due to malicious activities that Wordfence noticed and blocked in about 2 weeks of running the plugin on my blog site. While I could leave Wordfence to continue issuing the blocks, this should reduce overall traffic on my internet connection and reduce load on the WordPress server.
Hardening With pfSense and HAProxy
Cloudflare blocks malicious traffic globally, but pfSense + HAProxy enforce strict origin-level access control. This prevents attackers from bypassing Cloudflare and directly accessing your WordPress server.
This is where you enforce:
- Cloudflare-only access to your external WordPress frontend
- Internal-only access to /wp-admin and /wp-login.php
- Blocking of XML-RPC, plugin scanners, and exploit paths before WordPress runs
- Proper segmentation between public and administrative fronts
Step 1: pfSense Alias for Cloudflare IPs
pfSense can dynamically import Cloudflare’s published network ranges.
Go to:
Firewall → Aliases → Add → URL Table (IPs)
Add:
https://www.cloudflare.com/ips-v4
https://www.cloudflare.com/ips-v6
Name:
- Cloudflare_IPs
These auto-update, so pfSense always tracks Cloudflare’s active networks.
Step 2: Firewall Rules to Only Allow Cloudflare to Access HAProxy
Under Firewall → Rules → WAN:
- Allow TCP 443 from Cloudflare_IPs to This Firewall (self)
- Add a reject everything else rule at the bottom
Result:
No one except Cloudflare can reach HAProxy’s external WordPress frontend. Reject rules perform similar to block rules but with less application overhead on your firewall.
This prevents:
- Origin bypass attacks
- Direct DDoS
- Direct brute-force to wp-login
- Bots or bad actors bypassing Cloudflare protections
Step 3: Dual HAProxy Frontends (External + Internal)
External Frontend (Mapped to WAN interface or VIP)
- Public WordPress site
- Only Cloudflare IPs can reach it due to the above firewall rule
- /wp-login.php and /wp-admin fully denied and return 403 errors
- Blocks exploit paths and malicious URL probes if the Cloudflare rule fails
Cloudflare → WAN → HAProxy External Frontend
✔ Public website
✔ Protected by Cloudflare + HAProxy path ACLs
✔ Sensitive paths blocked entirely
Internal Frontend (LAN Interface)
- Binds to an internal RFC1918 address
- Accessed via LAN or VPN
- Used for WordPress administration
- Allows /wp-admin and /wp-login.php
- Bypasses Cloudflare caching
- Fast, local, no external routing
Internal Devices → Internal DNS → HAProxy Internal Frontend
✔ Full admin functionality
✔ Never exposed externally
✔ Immune to Internet-based brute force
HAProxy Public Frontend ACLs Protecting WordPress
| ACL Name | Path Contains | What It Blocks |
|---|---|---|
| wp_admin_path | /wp-admin | Public access to the WordPress dashboard; prevents admin enumeration, privilege-escalation attempts, and admin-area exploit scanning. |
| wp_login_path | /wp-login.php | All external login attempts; stops brute-force attacks, password spraying, credential stuffing, and botnet login floods. |
| wp_xmlrpc | /xmlrpc.php | Complete XML-RPC disablement; blocks amplified brute-force authentication, pingback exploits, and XML-RPC DoS vectors. |
| wp_alfa | /alfacgiapi/ | Blocks scanners targeting CGI-like script execution paths (seen frequently in Wordfence logs as part of automated cross-CMS scanning tools). |
| wp_json_ls | /wp-json/litespeed/ | Blocks LSCache-related vulnerability scanners and REST exploit payloads targeting LiteSpeed/LSAPI vectors. |
| wp_plugins | /plugins/ | Blocks cross-CMS plugin enumeration (Drupal/Joomla exploit kits hit this directory as part of reconnaissance). |
| wp_style | /style.php | Blocks attempts to execute uploaded backdoor shells (this filename is widely used by malware droppers). |
| wp_alfadata | /ALFA_DATA/ | Blocks another common CGI-style directory used in automated scanning for arbitrary file reads, uploads, and RCE vectors. |
Each of these is then set to an http-request deny action with a 403 status code. The Cloudflare rule above should block these requests before they even reach HAProxy, but they are added on the off-chance it doesn’t.

Fixing Cloudflare CDN-CGI Images When Using HAProxy Internal Frontend
When the Cloudflare WordPress plugin rewrites images using:
/cdn-cgi/image/<params>/https://yourdomain/…
This essentially serves your images from Cloudflare CDNs while using the image on your server as a fallback option. When accessing WordPress using an internal HAProxy frontend that bypasses Cloudflare, WordPress mis-handles these URLs, causing your images to stop loading for your intranet devices.
Add this fix above WordPress rules in .htaccess:
# Fix Cloudflare cdn-cgi/image URLs for all domains
RewriteCond %{REQUEST_URI} ^/cdn-cgi/image/.+?/https://([^/]+)/(.+)$ [NC]
RewriteRule ^ https://%1/%2 [R=302,L]Why This Fix Is Necessary
- Ensures internal admin access loads images properly
- Prevents WordPress from rewriting Cloudflare’s special paths
- Keeps Cloudflare Image Optimization fully functional
Mapping the Security Stack to OSI Layers
| OSI Layer | Component | What It Protects |
| Layer 3–4 | Cloudflare edge firewall, pfSense WAN rules | Blocks hostile IPs, origin bypass, direct DDoS |
| Layer 4–7 | HAProxy ACLs | Blocks sensitive paths, exploit URLs, shell execution |
| Layer 7 | Cloudflare WAF | Blocks XML-RPC, login attacks, REST exploit patterns |
| Layer 7 | Wordfence + RSS | Malware scanning, tamper detection, authentication security |
| Layer 7 | .htaccess rules | Fixes routing issues, prevents rewrite-based bypasses |
Conclusion
Hardening WordPress isn’t about relying on a single plugin or firewall rule—it’s about building a true defense-in-depth architecture where each layer protects the one beneath it. Cloudflare stops malicious traffic at the global edge, pfSense ensures only Cloudflare can ever reach your server, HAProxy enforces strict path-level and role-based access to WordPress, and Wordfence/RSS secure the application itself.
By segmenting WordPress into external and internal frontends, blocking high-risk paths early, and preventing origin bypass entirely, you eliminate many modern attack vectors aimed at WordPress sites today—including brute force, XML-RPC floods, plugin enumeration, upload-based shells, and cross-CMS scanners.
The result is a WordPress deployment that is:
- Faster, because Cloudflare and HAProxy absorb and reject malicious traffic before PHP gets involved
- More secure, because attackers cannot even reach sensitive endpoints
- Resilient, because every layer reinforces the next
- Low-maintenance, with drastically fewer Wordfence alerts and cleaner logs
- Fully optimized, with CDN-cgi image rewriting, Turnstile, and caching all functioning correctly
This architecture turns WordPress—often criticized for being insecure—into a hardened, highly controlled, multi-layered platform that is safe to operate even under heavy targeting. Whether you’re hosting a personal blog or a high-traffic business site, this layered approach gives you confidence that your environment is protected at every level, from the global edge down to the application core.

