Three Cloudflare WAF Rules for a WordPress Server

2026-02-15

Putting WordPress behind Cloudflare brings a CDN and HTTPS at the edge. It also gives you another place to deal with automated requests, including traffic that can make a small server slow even on a quiet day.

Two routes to inspect in WordPress logs are /wp-login.php and /xmlrpc.php. Repeated login submissions and abuse of XML-RPC methods can make the server do unnecessary work. Look for a connection between requests hitting those paths and any slowdowns you see.

Cloudflare’s Web Application Firewall can act on matching requests before forwarding them to your origin, provided the hostname is proxied and requests go through Cloudflare. The examples below show three ways to match traffic. Use the ones that fit how your site works.

In the dashboard layout used for this walkthrough, the path was as follows.

Cloudflare Dashboard → Security → WAF → Custom rules → Create rule


Find custom rules for your site

  1. Sign in to Cloudflare.
  2. Select the site you want to configure.
  3. Open Security → WAF → Custom rules, or Security rules in the newer dashboard.
  4. Choose Create rule and select Custom rules when prompted.

Custom rules run in order. A rule that blocks a request can stop evaluation, so check the order of your new rules against rules you already use.


Rule 1. Match traffic by country or territory

This example matches requests geolocated to China or Hong Kong.

Use this as an example of geographic matching, based on a documented site need. Block denies access to all users matching the expression. Managed Challenge asks Cloudflare to assess matching requests and can interrupt some legitimate users too.

Build the country match

Rule name

  • China_HK_Block
  • China_HK_Challenge, if you are testing the match with a challenge

Under When incoming requests match…, add the first condition.

  1. Field: Country (ip.src.country)
  2. Operator: equals
  3. Value: China

Add a second condition.

  1. Field: Country
  2. Operator: equals
  3. Value: Hong Kong

Connect the conditions with OR, so either location matches.

  • Match either condition (OR).
    • Country equals China.
    • Country equals Hong Kong.

If you prefer to work in the expression editor, enter the following.

(ip.src.country eq "CN") or (ip.src.country eq "HK")

Choose an action

  • Block denies every request that matches.
  • Managed Challenge gives a browser an opportunity to pass Cloudflare’s checks.

Select Deploy or save the rule for review.


Rule 2. Restrict the XML-RPC endpoint

This example matches paths containing xmlrpc.php. For a root-level WordPress install, matching the exact path /xmlrpc.php is narrower.

First verify whether Jetpack, a mobile app or another publishing tool uses XML-RPC on your site. If nothing depends on the endpoint, you can choose Block for this path.

Build the XML-RPC match

Rule name

  • WP_Block_XMLRPC

Add a condition.

  1. Field: URI Path
  2. Operator: contains
  3. Value: xmlrpc.php

Choose an action

  • Block

Select Deploy or save the rule for review.

The example expression uses a contains match.

(http.request.uri.path contains "xmlrpc.php")

Rule 3. Challenge requests to the login page

This rule matches the default WordPress login path. If you changed it, match the path you actually use.

A blanket block on the login path can lock out your own users or administrators. Managed Challenge is an option when people sign in through a browser. Test the workflows that use this path before deployment.

Build the login match

Rule name

  • WP_Login_ManagedChallenge

Add a condition.

  1. Field: URI Path
  2. Operator: contains
  3. Value: /wp-login.php

Choose an action

  • Managed Challenge

Select Deploy or save the rule for review.

The expression for this example looks like this.

(http.request.uri.path contains "/wp-login.php")

Check the rules after deployment

Aim to reduce unwanted traffic while keeping the site usable. A rule that matches many requests can be too broad even if a chart shows a dramatic drop at the origin.

If you are unsure what a geographic rule will catch, start with Log if your plan offers it, or test with Managed Challenge and inspect the events. A geographic block is an access policy for a whole location. It cannot tell a legitimate reader from a bot in the same place.

The login path has to remain available to people who sign in. A Managed Challenge may help with browser logins, but an automated integration may be unable to pass it. Test password resets and any other flows that share the path before you rely on the rule.

Try the login in a private browser window, and keep an existing administrator session open while you test. Also try any Jetpack connection, mobile app or other remote publishing tool the site depends on. If one uses XML-RPC, review which paths and clients actually need access before deploying a block.

In Cloudflare’s Security Events view, check which rules matched requests and what actions they took. Compare that with origin logs over the same period to see which requests still get through.

Start with a pattern you can see in the logs, verify what each rule matches, and measure the traffic that still reaches WordPress. If the site remains slow after unwanted requests fall, the origin needs its own investigation.

Search stories