Understanding security exposures and missing headers detected by our scanner. Click any item to learn what it means, why it matters, and how to fix it.
Critical Issues
🦠 Malware Detection
Critical Severity
What We Detect
Our scanner looks for common malware patterns in your site's HTML output:
- Obfuscated code:
eval(base64_decode(...)), eval(gzinflate(...)) - code designed to hide its true purpose
- Known backdoors: FilesMan, WSO, c99shell, r57shell, b374k - popular hacker tools
Why It Matters
If malware is detected on your site:
- Your site may be sending spam or hosting phishing pages
- Visitors could be redirected to malicious sites
- Google may blacklist your domain
- Your hosting provider may suspend your account
How to Fix
- Don't panic — but act quickly
- Take a backup of your current state (for forensics)
- Scan with multiple tools: Wordfence, Sucuri SiteCheck, or MalCare
- Check recently modified files:
find /var/www -mtime -7 -type f
- Review wp-config.php for injected code at the top or bottom
- Check .htaccess in all directories for redirects
- Update everything: WordPress core, themes, and plugins
- Change all passwords: WordPress admin, FTP, database, hosting panel
- Consider professional help: Sucuri or Wordfence offer malware removal services
💀 Fatal PHP Errors
High Severity
What It Means
Your site is displaying PHP fatal errors publicly. Common examples:
Fatal error: Allowed memory size exhausted
Fatal error: Cannot redeclare function
Parse error: syntax error, unexpected
Fatal error: Class 'ClassName' not found
Why It Matters
Publicly visible PHP errors expose:
- Full server paths: Reveals your hosting structure
- Plugin/theme names: Helps attackers find vulnerabilities
- PHP version: Useful for version-specific exploits
- Function names: Reveals internal code structure
Plus, your site is likely broken for visitors!
How to Fix
- Disable debug display in wp-config.php:
define('WP_DEBUG', false);
define('WP_DEBUG_DISPLAY', false);
define('WP_DEBUG_LOG', true); // Log errors instead
- Check PHP error log at
/wp-content/debug.log
- Fix the underlying issue:
- Memory exhausted → Increase PHP memory limit
- Class not found → Reinstall affected plugin/theme
- Syntax error → Revert recent code changes
- Set PHP error reporting in php.ini or .htaccess:
php_flag display_errors Off
php_flag log_errors On
Exposed Files
Debug Log High Severity
Path: /wp-content/debug.log
What is it?
When WordPress debugging is enabled, PHP errors, warnings, and notices are written to a file called debug.log. This file is meant for developers to troubleshoot issues during development.
Why is it dangerous?
- Reveals server file paths (helps attackers map your system)
- Shows which plugins/themes have errors (identifies weak points)
- May contain database query errors (can expose table structure)
- Can contain sensitive data logged by poorly coded plugins
- Signals to attackers that debugging is enabled
How to fix it
Option 1: Disable debugging in wp-config.php:
define('WP_DEBUG', false);
define('WP_DEBUG_LOG', false);
Option 2: Block access via .htaccess (Apache):
<Files debug.log>
Order allow,deny
Deny from all
</Files>
Option 3: Block access via Nginx:
location ~* debug\.log$ {
deny all;
}
Option 4: Delete the file if you don't need it:
rm wp-content/debug.log
Error Log High Severity
Path: /error_log or /error.log
What is it?
The PHP error log captures runtime errors from your server. It's similar to debug.log but is created by PHP itself rather than WordPress.
Why is it dangerous?
- Contains full server file paths
- May reveal database connection errors with credentials
- Shows PHP version and configuration details
- Exposes application logic through stack traces
How to fix it
Move error logs outside the web root in php.ini:
error_log = /var/log/php/error.log
Or block access via .htaccess:
<Files ~ "^error[_\.]?log$">
Order allow,deny
Deny from all
</Files>
PHP Info Medium Severity
Common paths: /info.php, /phpinfo.php, /php.php, /i.php
What is it?
A PHP file containing phpinfo() which outputs detailed information about your server's PHP configuration. Often left behind after initial server setup or debugging.
Why is it dangerous?
- Reveals exact PHP version (allows targeting known vulnerabilities)
- Shows all loaded PHP modules
- Displays server paths and environment variables
- May expose database hostnames and internal IPs
- Shows email configuration (SMTP settings)
How to fix it
Simply delete the file:
rm info.php phpinfo.php php.php i.php
If you need phpinfo for debugging, protect it:
<Files "phpinfo.php">
Require ip 127.0.0.1
Require ip YOUR.IP.ADDRESS
</Files>
Install.php Critical Severity
Path: /wp-admin/install.php
What is it?
The WordPress installation script. On a properly configured site, this should not be accessible after initial setup.
Why is it dangerous?
- An attacker could potentially reinstall WordPress
- If database tables are dropped, the installer becomes active again
- Can be used to create a new admin account
- Indicates the site may have configuration issues
How to fix it
Block access via .htaccess:
<Files install.php>
Order allow,deny
Deny from all
</Files>
Or via Nginx:
location = /wp-admin/install.php {
deny all;
}
XML-RPC Medium Severity
Path: /xmlrpc.php
What is it?
XML-RPC is a remote procedure call protocol that allows external applications to communicate with WordPress. It was used for features like pingbacks, the mobile app, and remote publishing.
Why is it dangerous?
- Brute force amplification: Attackers can try hundreds of passwords in a single request
- DDoS attacks: Can be used in pingback-based DDoS attacks
- Username enumeration: Reveals valid usernames
- Most sites don't need it (REST API replaced most functions)
How to fix it
Block access via .htaccess:
<Files xmlrpc.php>
Order allow,deny
Deny from all
</Files>
Or disable via plugin or functions.php:
add_filter('xmlrpc_enabled', '__return_false');
Note: If you use the WordPress mobile app or Jetpack, you may need XML-RPC enabled.
Exposed Directories Medium Severity
Common paths: /backup/, /dev/, /staging/, /old/, /test/
What is it?
Directories that are publicly accessible and may contain sensitive files, backups, or development code that shouldn't be exposed to the internet.
Why is it dangerous?
- Backup folders: May contain database dumps with all your data
- Dev/staging folders: Often have debugging enabled and weaker security
- Old folders: May contain outdated, vulnerable WordPress versions
- Directory listing shows all files to attackers
How to fix it
Disable directory listing in .htaccess:
Options -Indexes
Or remove/protect the directories:
# Delete if not needed
rm -rf /var/www/html/backup/
# Or password protect
<Directory "/var/www/html/backup">
AuthType Basic
AuthName "Restricted"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user
</Directory>
Security Headers
Security headers are HTTP response headers that tell browsers how to behave when handling your site's content. They add an extra layer of protection against common attacks.
HSTS (Strict-Transport-Security) Medium Severity
What is it?
HSTS tells browsers to only connect to your site via HTTPS, even if the user types http:// or clicks an HTTP link.
Why is it important?
- Prevents SSL stripping attacks (man-in-the-middle)
- Protects users on public WiFi
- Ensures all traffic is encrypted
How to add it
Apache (.htaccess):
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Nginx:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
CSP (Content-Security-Policy) Medium Severity
What is it?
CSP tells the browser which sources of content (scripts, styles, images, etc.) are allowed to load. It's a powerful defense against cross-site scripting (XSS) attacks.
Why is it important?
- Blocks malicious scripts injected by attackers
- Prevents unauthorized content from loading
- Stops clickjacking attempts
How to add it
Start with a report-only policy to test:
Content-Security-Policy-Report-Only: default-src 'self';
Basic production policy:
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline';
Note: CSP requires careful configuration. Test thoroughly before enabling.
X-Content-Type-Options Low Severity
What is it?
This header prevents browsers from "sniffing" the content type and interpreting files differently than declared.
Why is it important?
- Prevents MIME-type confusion attacks
- Stops browsers from executing uploaded files as scripts
How to add it
Apache:
Header always set X-Content-Type-Options "nosniff"
Nginx:
add_header X-Content-Type-Options "nosniff" always;
X-Frame-Options Medium Severity
What is it?
Controls whether your site can be embedded in frames/iframes on other sites.
Why is it important?
- Prevents clickjacking attacks
- Stops attackers from embedding your site in a malicious page
How to add it
Apache:
Header always set X-Frame-Options "SAMEORIGIN"
Nginx:
add_header X-Frame-Options "SAMEORIGIN" always;
Referrer-Policy Low Severity
What is it?
Controls how much referrer information is sent when users click links to other sites.
Why is it important?
- Protects user privacy
- Prevents leaking sensitive URLs (e.g., password reset links)
How to add it
Apache:
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Nginx:
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
Permissions-Policy Low Severity
What is it?
Controls which browser features (camera, microphone, geolocation, etc.) your site can use. Formerly known as Feature-Policy.
Why is it important?
- Limits attack surface by disabling unused features
- Prevents malicious scripts from accessing sensitive APIs
How to add it
Apache:
Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()"
Nginx:
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
Proactive security measures that prevent attacks before they reach your WordPress site.
Web Application Firewalls (WAF) Recommended
What is a WAF?
A Web Application Firewall sits between your website and the internet, filtering malicious traffic before it reaches your server. WAFs block common attacks like SQL injection, XSS, and brute force attempts automatically.
Why does this matter for our scans?
Sites protected by a WAF often block our security scanner, which means we can't check for exposures or missing headers. This is actually a good thing! If a WAF blocks our scanner, it would also block malicious bots and attackers trying to find the same vulnerabilities.
Our detection rate would be nearly twice as high without WAFs — but we'd rather see sites protected than exposed. We focus on helping the ~30-40% of sites that don't yet have this layer of protection.
Popular WAF Options
Cloudflare (Recommended for most sites)
- Free tier available with basic WAF protection
- Also provides CDN, DDoS protection, and SSL
- Easy setup — just change your nameservers
- Pro plan ($20/mo) adds advanced WAF rules
Setup: Sign up at cloudflare.com → Add your site → Update nameservers at your registrar → Enable "Under Attack Mode" if needed.
Wordfence (WordPress-specific)
- WordPress plugin with built-in firewall
- Free version includes endpoint firewall
- Premium ($119/year) adds real-time threat intelligence
- Also includes malware scanning and login security
Setup: Install plugin → Go to Wordfence → Firewall → Optimize Firewall → Follow the prompts.
Sucuri
- Cloud-based WAF with malware cleanup service
- Plans start at $199/year
- Includes CDN and performance optimization
- 24/7 security team for incident response
All-In-One WP Security (Free)
- Free WordPress plugin with basic firewall rules
- Includes login lockdown and file integrity monitoring
- Good starting point for budget-conscious sites
Which should you choose?
- Small sites / blogs: Cloudflare Free + Wordfence Free
- Business sites: Cloudflare Pro or Sucuri
- WooCommerce / high-traffic: Cloudflare Business or Sucuri with their CDN
- Enterprise: Cloudflare Enterprise or dedicated WAF appliance
Quick Win: Enable Cloudflare in 10 Minutes
- Go to cloudflare.com and create a free account
- Enter your domain and let Cloudflare scan your DNS
- Review the DNS records (usually auto-detected correctly)
- Update your domain's nameservers at your registrar
- Wait for propagation (usually 5-30 minutes)
- Enable "Always Use HTTPS" in SSL/TLS settings
- Turn on "Bot Fight Mode" in Security settings
That's it — your site now has basic WAF protection, DDoS mitigation, and a global CDN for free.