Most WordPress security issues come from basics nobody checks. PHP execution in the uploads folder. Exposed wp-config.php backups. Missing security headers. Weak file permissions.
The fixes are simple. The problem is nobody audits for them.
That's why I built wpsec109 — a free, open-source scanner that checks 109 WordPress security hardening points across 22 categories in about 60 seconds.
What It Checks
1. Directory Listing (7 checks)
Checks whether /wp-content/, /wp-content/plugins/, /wp-content/uploads/, and other directories allow directory listing. Exposed directories reveal file structures to attackers.
2. PHP Execution Blocking (18 checks)
The critical one: tests whether PHP can execute in /wp-content/uploads/. Tests 5 extension variants:
.php.phar.phtml-
.php0through.php9 - Double-extension bypasses:
.php.jpg,.php;.jpg,.php%00.jpg
3. Sensitive Files (14 checks)
- Exposed
wp-config.phpand backups (.bak,.old,.save,.txt) - Exposed
.gitdirectory and.envfiles - Exposed
readme.htmlandlicense.html
4. Security Headers (6 checks)
X-Frame-OptionsX-Content-Type-OptionsContent-Security-Policy-
Strict-Transport-Security(HSTS) - Referrer-Policy
- Permissions-Policy
5. User Enumeration (3 checks)
-
/wp-json/wp/v2/users/accessibility -
/?author=1enumeration -
/wp-admin/admin-ajax.phpuser enumeration
6. File Permissions (9 checks)
-
wp-config.phppermissions -
.htaccesspermissions - Directory permissions
7. wp-config.php Hardening (7 checks)
DISALLOW_FILE_EDITDISALLOW_FILE_MODSFORCE_SSL_ADMIN- Security salts presence
- Database prefix
8. Core File Integrity (1 check)
MD5 checksums against official WordPress API.
9. WPScan Integration (4 checks)
Plugin and theme CVE cross-reference (requires API key).
Usage
# Clone the repo
git clone https://github.com/damianhunziker/Wordpress-security-check.git
cd wordpress-security-check
# Run a basic scan
python wordpress_security_check.py --target https://example.com
# Run with WPScan integration
python wordpress_security_check.py --target https://example.com --wpscan-api-key YOUR_KEY
# Generate JSON report
python wordpress_security_check.py --target https://example.com --save report.json
# Interactive mode
python wordpress_security_check.py --target https://example.com --interactive
Sample Output
==================================================
WordPress Security Check - Scan Report
Target: https://example.com
Scan Duration: 47 seconds
==================================================
[CRITICAL] PHP Execution in /wp-content/uploads/
Impact: An attacker can upload a webshell and gain code execution.
Fix: Add the following to /wp-content/uploads/.htaccess:
<FilesMatch "\.(php|phar|phtml)$">
Require all denied
</FilesMatch>
[HIGH] wp-config.php.bak exposed
Impact: Attacker can read database credentials.
Fix: Remove the backup file or move it outside the web root.
[MEDIUM] X-Frame-Options header missing
Impact: Site is vulnerable to clickjacking attacks.
Fix: Add 'X-Frame-Options: DENY' to .htaccess or server config.
[LOW] readme.html exposes WordPress version
Impact: Attackers can target version-specific vulnerabilities.
Fix: Delete readme.html from the web root.
==================================================
Summary: 109 checks run | 4 failed | 105 passed
Critical: 1 | High: 1 | Medium: 1 | Low: 1
==================================================
Why Open Source?
I needed a scanner for client work that:
- Didn't require API keys
- Ran locally without sending data to third parties
- Provided actionable remediation guidance
Nothing did all three, so I built it.
Get Started
MIT licensed. No API keys required. Runs on Python 3.8+.
Top comments (0)