CloudFlare recently added Firewall Rules to all accounts, including free accounts. With these rules, you can help protect your WordPress installation against common attacks for both known and undisclosed vulnerabilities.
First, log in to your CloudFlare account, then click the Firewall button in the toolbar at the top of the page.
Next, in the Firewall Rules section at the top of the page content, click the Create a Firewall Rule button.
LOGIN PROTECTION FIREWALL RULE
The first firewall rule we will add will help protect the WordPress login page.
- Give your rule a name, such as “Login Protection.”
- Select URI Path as the Field, contains as the Operator, /wp-login.php as the Value.
Note: The reason we don’t use equals as the Operator is because it could be easily circumvented if the attacker used a URI Path of //wp-login.php (a double slash in a URI Path is interpreted as a single slash on most web servers).
- Set the rule Action to Challenge (Captcha).
Your rule form should look like this:
Click the Save and Deploy button. Test your new firewall rule by trying to log in to your WordPress web site. You should be presented with a CAPTCHA which you must answer correctly before being given access to the WordPress login page. If not, check your firewall rule for typos and selection errors.
This firewall rule will stop all automated attacks on your login page. However, it will not stop login attacks against the REST or XMLRPC interfaces of your WordPress site. There are many security plugins available for WordPress that can help protect those interfaces from attacks on your web site.
VULNERABLE PLUGIN AND ROGUE PHP FILE BLOCKING RULE
The next firewall rule we will add will help protect your WordPress web site from attacks on vulnerable plugins. It will also stop access to PHP files a hacker might have managed to upload to your site.
- Give your rule a name, such as “Content Protection.”
- Select URI Path as the Field, contains as the Operator, and /wp-content/ as the Value.
- Click the And button to add another match specification.
- For the added match specification, select URI Path as the Field, contains as the Operator, and .php as the Value.
Note: If you have a paid CloudFlare account, this is unnecessary. You can use a single match operator and specify a regular expression to detect access to PHP files in the /wp-content/ folder.
- Set the rule Action to Block.
Your rule form should look like this:
Click the Save and Deploy button. Test your new firewall rule by trying to directly access any PHP file in the /wp-content/ folder. For example, if you have the WP Super Cache plugin installed, try accessing https://<my-web-site.com>/wp-content/plugins/wp-super-cache/wp-cache.php and you should get an Access Denied response from CloudFlare.
Note: Properly designed themes and plugins should never require direct access to PHP files in the /wp-content/ folder. If your theme or one of your plugins stops working after adding this firewall rule, be sure to complain to the maker of that theme or plugin. Better yet, uninstall it, because the developer can not be trusted if they made such a basic design mistake.
THE EXPRESSION EDITOR
Under the inputs for the Firewall Rule form you will notice the Expression Preview text box. This provides an easy way to copy and share Firewall Rules. Click the Edit Expression link to switch into the Expression Editor mode.
Try adding these new blocking rules in the Expression Editor mode:
- Block attempts to download the WordPress configuration file…
(http.request.full_uri contains "wp-config.")
- Block all attempts to access WordPress REST API (do not use if you have JetJack or other plugins installed that rely on REST)…
(http.request.uri.path contains "/wp-json/")
- Block author name scanning (sometimes a precursor to brute-force login attacks, but could also be search engines trying to discover content)…
(http.request.uri.query contains "author_name=") or (http.request.uri.query contains "author=" and not http.request.uri.path contains "/wp-admin/export.php")
- Block attempts to access phpMyAdmin through your public web site. Hopefully you aren’t allowing that anyway, but why waste your web server’s time processing attempts to access it?
(http.request.uri.path contains "phpmyadmin")
- Block attempts to access the filesystem outside of the web site’s directory. Be careful with this one since some poorly written CSS or HTML might make use of this to access assets in directories above it in the file system. Also check the URI for the escaped value of / which is %2F since this is often used in scripting attacks.
(http.request.full_uri contains "../") or (http.request.uri contains "..%2F")
- Block attempts to access the password file by exploiting buggy plugins or themes.
(http.request.uri contains "passwd")
COMBINE FIREWALL RULES
As we can see, the expression editor allows the use of parenthesis and the logical operators and and or. This means we can combine all rules that use the same Action into a single rule. To protect a WordPress site with all the rules we have made so far, we can reduce them down to two rules; one that combines all the Block rules, and another for the Challenge action when someone accesses the login page.
- Login Protection:
Action: Challenge (Captcha)
(http.request.uri.path contains "/wp-login.php")
- Content Protection:
(http.request.uri.query contains "author_name=") or (http.request.uri.query contains "author=" and not http.request.uri.path contains "/wp-admin/export.php") or (http.request.full_uri contains "wp-config.") or (http.request.uri.path contains "/wp-json/") or (http.request.uri.path contains "/wp-content/" and http.request.uri.path contains ".php") or (http.request.uri.path contains "phpmyadmin") or (http.request.full_uri contains "../") or (http.request.uri contains "..%2F") or (http.request.uri contains "passwd")
Check out the CloudFlare Firewall Rules documentation for more information and ideas on how to put this powerful feature to work.
These firewall rules will stop a lot of attacks on your web site. Just return to your CloudFlare account in a 24 hours and look at the Firewall Events log at the bottom of the Firewall page. You will see at least a dozen attacks blocked by these rules. Don’t take it personally, these attackers most likely do not know you.
However, this is not 100% protection for your WordPress site. Some additional things you can do to protect your site are:
- Keep WordPress, your theme and plugins up-to-date. Read the Configuring Automatic Background Updates article to learn how to update your web site as soon as updates are available.
- Review and follow the advice given in the Hardening WordPress article.
- Add a WordPress security plugin like NinjaFirewall.
- Install and configure server level protection, such as mod_security, Fail2Ban, and bad bot blockers. Note: If you aren’t running your own web server, your web hosting company should be taking care of server level protection for you.
- Cloudflare offers a paid Web Application Firewall service which is a like having the firewall rules outlined in this article, plus many more, all kept up-to-date by their engineers.