Cloudflare WAF for WordPress: A Configuration Guide

Cloudflare WAF for WordPress: A Configuration Guide

Every WordPress site faces automated probes — credential stuffing on /wp-login.php, XML-RPC amplification, REST API enumeration, and targeted plugin exploits. A Web Application Firewall at the network edge intercepts these before they reach your PHP runtime. Cloudflare WAF, backed by its global anycast network, is the most practical implementation for WordPress operators at scale.

This guide covers a production-grade Cloudflare WAF configuration: managed rulesets, OWASP tuning, custom rules for WordPress attack surfaces, rate limiting, bot management, and avoiding false positives that break WooCommerce checkout.

What a WAF Does

A WAF inspects HTTP/HTTPS requests at Layer 7 against known attack signatures and behavioral heuristics. When a request matches, the WAF can log, challenge, or block it before it reaches your origin. It is a complementary control — not a substitute for patching plugins or enforcing strong credentials — that is especially effective against OWASP Top 10 vectors: SQL injection, XSS, and remote file inclusion. Cloudflare evaluates every request, including WooCommerce REST API calls, before traffic touches your server.

Managed Rulesets

Cloudflare provides two managed rulesets for WordPress deployments:

  • Cloudflare Managed Ruleset — Proprietary signatures updated continuously from global threat intelligence, including WordPress plugin and theme CVEs.
  • Cloudflare OWASP Core Ruleset — A port of the ModSecurity CRS covering generic attack patterns. Requires paranoia level tuning on WooCommerce sites to avoid false positives on checkout POST bodies.

Enable both under Security → WAF → Managed Rules. Set the Cloudflare Managed Ruleset to Block. Set OWASP to Log initially — promote to Block only after a 72-hour review period. Use paranoia level PL1 for WooCommerce; PL2+ will flag legitimate cart and address field content.

Threat → Cloudflare Control Reference

Threat Cloudflare Control Recommended Action
Brute-force on /wp-login.php Rate Limiting + Custom Rule Block after 5 POST requests / 60 s
XML-RPC exploitation Custom Rule (URI path match) Block (Jetpack IP bypass if needed)
wp-admin from untrusted IPs Custom Rule (IP/ASN allowlist) Managed Challenge non-allowlisted sources
REST API user enumeration Custom Rule (URI match) Block /wp-json/wp/v2/users
SQL injection / XSS OWASP Core Ruleset (CRS) Log → Block at PL1 after review
Plugin/theme CVE exploits Cloudflare Managed Ruleset Block
Credential stuffing / scraping Bot Fight Mode / Super Bot Fight Mode Managed Challenge or Block
High-risk country/ASN traffic Custom Rule (country/ASN field) Challenge or Block per geography
WooCommerce REST API abuse Rate Limiting (scoped to /wp-json/wc/) Rate-limit; skip block for auth tokens

Custom Rules for WordPress Attack Surfaces

Protect wp-login.php

Create a custom WAF rule matching (http.request.uri.path contains "/wp-login.php") with action Managed Challenge, bypassed for your administrative IP ranges. This presents a CAPTCHA to credential-stuffing bots while allowing your team through without friction.

Block xmlrpc.php

Match (http.request.uri.path eq "/xmlrpc.php") with action Block. If Jetpack is active, scope the bypass to Jetpack’s published IP ranges rather than disabling the rule. Do not leave this endpoint open — it is the most abused vector for WordPress brute-force amplification.

Restrict wp-admin by IP or ASN

If the URI path starts with /wp-admin and the source IP is not in your allowlist, apply Managed Challenge. For teams on a VPN with a static exit ASN, use an ASN match for the bypass — easier to maintain than individual IP lists and covers remote workers automatically.

Block REST API User Enumeration

Block /wp-json/wp/v2/users with a URI path match rule. This does not affect WooCommerce REST API endpoints under /wp-json/wc/. Audit your active plugins’ REST API dependencies before broader /wp-json/ restrictions.

Rate Limiting Login Attempts

Under Security → WAF → Rate Limiting Rules, create a rule for http.request.uri.path eq "/wp-login.php" AND http.request.method eq "POST". Threshold: 5 requests / 60 seconds per IP. Action: Block for 10 minutes. Apply the same logic to /my-account/ POST requests for customer-facing WooCommerce login forms.

Bot Fight Mode

Enable Super Bot Fight Mode (Business/Enterprise) or Bot Fight Mode (Pro) under Security → Bots. Verified bots (Googlebot, Bingbot) are automatically allowlisted. Unverified automated traffic receives a Managed Challenge.

Create WAF Skip rules for verified payment gateway IP ranges (Stripe and PayPal publish these) and your own application servers. Headless storefronts and webhook senders using server-side HTTP clients can be mis-scored as bots, breaking WooCommerce checkout.

Country and ASN Rules

For region-specific businesses, match not (ip.geoip.country in {"US" "GB" "SG"}) with action Managed Challenge — this adds friction without a hard block, preserving access for legitimate international users. Reserve full country blocks for ASNs or regions with zero legitimate customer base. Review ASN blocklists quarterly.

Avoiding False Positives on WooCommerce

The OWASP ruleset’s SQLi and XSS signatures fire on legitimate WooCommerce request bodies: product search queries with special characters, address apostrophes, and base64-encoded metadata are common triggers. Mitigation:

  • Run OWASP in Log mode for 72 hours minimum before switching to Block.
  • Filter Firewall Events by action=log and ruleset=OWASP. Identify the specific rule IDs firing on /checkout/, /cart/, and /wp-json/wc/.
  • Create WAF Exception rules scoped to those exact rule IDs and paths — never skip the entire ruleset for a path.
  • Exempt authenticated WooCommerce REST API requests by matching the Authorization header, preserving WAF coverage for unauthenticated traffic.

Vilee LLC combines deep technical expertise in WordPress/WooCommerce development with AI-powered automation to operate 520+ profitable online businesses at scale.

Testing in Log Mode First

Before any new rule goes to Block, run it in Log mode for at least 48 hours. Review the Firewall Events log and confirm matched requests are genuine threats. For ecommerce, include a full weekend in the review window before promoting to Block. Use Cloudflare’s Rule Preview in the custom rules editor to test expressions against recent traffic before saving.

Configuration Checklist

  • Enable Cloudflare Managed Ruleset — Block
  • Enable OWASP Core Ruleset — Log, PL1
  • Custom rule: Managed Challenge on /wp-login.php with IP bypass
  • Custom rule: Block /xmlrpc.php (Jetpack IP bypass if active)
  • Custom rule: Managed Challenge on /wp-admin for non-allowlisted IPs/ASNs
  • Custom rule: Block /wp-json/wp/v2/users
  • Rate limit rule: 5 POST / 60 s on /wp-login.php, Block 10 min
  • Enable Bot Fight Mode or Super Bot Fight Mode
  • WAF Skip rules for payment gateway and application server IPs
  • Review Firewall Events log for 72 hours in Log mode
  • WAF Exceptions for OWASP rule IDs triggering on WooCommerce paths
  • Promote OWASP from Log to Block after clean review
  • Country/ASN rules per customer geography
  • Quarterly review of exceptions and ASN blocklist

Cloudflare WAF is not a set-and-forget control — it requires ongoing review as your plugin stack and traffic patterns evolve. Vilee’s team handles this operationally across our services portfolio, maintaining WAF configurations that protect production stores without disrupting legitimate customer traffic. Need a WAF audit or managed configuration for your WordPress environment? Contact us.

Frequently Asked Questions

Will Cloudflare WAF break my WooCommerce REST API?

It can, if the OWASP ruleset is set to Block without a prior log review. WooCommerce REST API requests can match SQLi or XSS signatures due to special characters in product data. Run OWASP in Log mode for 72 hours, identify the rule IDs firing on /wp-json/wc/, and create scoped WAF Exceptions for those IDs only.

Should I block xmlrpc.php entirely?

For most WordPress sites, yes. XML-RPC is exploited for brute-force amplification and DDoS reflection. Unless Jetpack or another integration explicitly requires it, block /xmlrpc.php via a Cloudflare custom rule. If Jetpack is active, scope the bypass to Jetpack’s published IP ranges.

What Cloudflare plan do I need for WAF on WordPress?

Pro ($20/month per zone) is the minimum — it unlocks the Cloudflare Managed Ruleset, OWASP Core Ruleset, and Rate Limiting rules. Super Bot Fight Mode requires the Business plan. Enterprise adds full threat intelligence, advanced rate limiting, and dedicated WAF support. For most WooCommerce operators, Business is the right tier.

Frequently Asked Questions

Will Cloudflare WAF break my WooCommerce REST API?

It can, if the OWASP ruleset is set to Block without a log review period. WooCommerce REST API requests that include product data with special characters or base64-encoded metadata may match SQL injection or XSS signatures. The correct approach is to run the OWASP ruleset in Log mode for 72 hours, identify the specific rule IDs generating false positives against /wp-json/wc/ endpoints, and create scoped WAF Exceptions for those rule IDs only.

Should I block xmlrpc.php entirely?

For most WordPress sites, yes. XML-RPC is exploited for brute-force credential attacks and DDoS amplification. Unless you have an active integration that requires it — Jetpack being the most common exception — blocking /xmlrpc.php via a Cloudflare WAF custom rule is the correct security posture. If Jetpack is active, scope the bypass to Jetpack’s published server IP ranges.

What Cloudflare plan do I need for WAF on WordPress?

The Cloudflare Pro plan ($20/month per zone) is the minimum for accessing the Cloudflare Managed Ruleset and the OWASP Core Ruleset. Super Bot Fight Mode requires the Business plan. Enterprise plans add full threat intelligence feed, advanced rate limiting, and dedicated WAF rule management support. For most WooCommerce operators, the Business plan provides the right balance of control and automation.

Talk to us →