A Web Application Firewall sits between your web server and the internet, inspecting HTTP traffic for attacks — SQL injection, cross-site scripting, file inclusion, and the endless stream of automated exploits that target every public website.
What a WAF actually does
A WAF is not a network firewall. It does not block ports or IPs (well, it can, but that is not its job). A WAF inspects HTTP request content:
- Request body — looking for SQL injection, XSS payloads, malicious file uploads
- Headers — detecting malformed requests, user-agent patterns of known attack tools
- URL parameters — blocking path traversal, command injection attempts
- Response body — some WAFs can strip sensitive data from responses (credit card numbers, error details)
Do you need a WAF?
If you run WordPress: Yes. WordPress is the single most targeted CMS, and automated scanners hit every WordPress site continuously. A WAF blocks most of these before they reach your application.
If you run a custom application: Probably yes, unless you have a dedicated security team reviewing every commit. A WAF is a safety net.
If you run a static site: A WAF adds limited value, but Cloudflare’s free tier gives you DDoS protection and caching — worth it for the CDN alone.
Option 1: Cloudflare WAF (managed, free tier available)
Cloudflare’s free plan includes a managed WAF with rulesets updated by Cloudflare’s security team. Setup takes five minutes:
- Add your domain to Cloudflare
- Update nameservers
- Enable “Web Application Firewall” in the Security menu
- Set the sensitivity — start with “Medium” and adjust
Cloudflare’s WAF automatically blocks:
- SQLi and XSS attempts
- WordPress-specific exploits (xmlrpc.php attacks, known plugin vulnerabilities)
- File inclusion and directory traversal
- Common bot patterns
The free tier blocks most automated attacks. The Pro tier ($20/month) adds custom rules and more granular controls.
Option 2: ModSecurity (self-hosted, open source)
ModSecurity is the OWASP-backed WAF engine. It runs on your server alongside Apache or Nginx.
Installing ModSecurity with Nginx
# Ubuntu/Debian
sudo apt update
sudo apt install libmodsecurity3 nginx-module-modsecurity
# Enable in nginx.conf
load_module modules/ngx_http_modsecurity_module.so;
# In your server block
modsecurity on;
modsecurity_rules_file /etc/nginx/modsecurity/modsecurity.conf;
OWASP Core Rule Set
The OWASP CRS is the standard ruleset for ModSecurity. It is actively maintained and covers the OWASP Top 10:
git clone https://github.com/coreruleset/coreruleset.git /etc/nginx/modsecurity-crs
cp /etc/nginx/modsecurity-crs/crs-setup.conf.example /etc/nginx/modsecurity-crs/crs-setup.conf
Tuning ModSecurity (the essential step)
Out of the box, ModSecurity with CRS will block legitimate WordPress admin actions. You need to tune it:
# In modsecurity.conf
SecRuleEngine On
SecRule REQUEST_URI "@beginsWith /wp-admin" \
"id:1000,phase:1,pass,log,msg:'WordPress admin bypass'"
Common false positives on WordPress:
- Gutenberg block saves — blocked as “potential XSS” because they contain HTML
- Plugin uploads — blocked as “file inclusion”
- WooCommerce checkout — blocked for POST body patterns
Start in “DetectionOnly” mode (SecRuleEngine DetectionOnly) for a week. Review the audit log, whitelist legitimate patterns, then switch to “On”.
Option 3: Wordfence / Sucuri (WordPress-specific)
If you only need to protect WordPress and do not want to manage server-level WAF rules:
- Wordfence (free + premium): Endpoint firewall that runs inside WordPress. It knows WordPress internals and has very few false positives.
- Sucuri (paid): Cloud-based WAF + CDN. Traffic passes through Sucuri’s network before reaching your server.
The downside of plugin-based WAFs: they run as PHP, so an uncaught vulnerability at the PHP level could bypass the WAF. Cloud-based or server-level WAFs provide an extra layer.
WAF deployment patterns
Internet → Cloudflare WAF → Server (ModSecurity) → WordPress
This gives you two layers of WAF. Cloudflare blocks most automated noise at the edge. ModSecurity catches anything that gets through — and protects you if Cloudflare is bypassed.
Monitoring and maintenance
Check what your WAF is blocking
# ModSecurity audit log
tail -f /var/log/nginx/modsec_audit.log
# Count blocked requests by rule
grep -c "ModSecurity: Access denied" /var/log/nginx/error.log
Review false positives weekly
A WAF that blocks real users is worse than no WAF. Check the audit log for requests from real IPs (not scanners) that got blocked. Whitelist them.
Update rules regularly
# OWASP CRS
cd /etc/nginx/modsecurity-crs
git pull
systemctl reload nginx
The minimum viable WAF setup
For a WordPress site on a budget:
- Cloudflare free tier (WAF + CDN + DDoS)
- A WordPress security plugin (Wordfence free is fine)
- Cloudflare page rules to rate-limit
wp-login.phpandxmlrpc.php
This blocks 95% of attacks with zero server overhead and minimal configuration.