Website security can and should be done in layers. Cloudflare is a great cloud security service that offers protection at their globally distributed servers, before they reach your website’s origin servers. But even the best firewall rules won’t be able to stop all malicious requests crafted by smart hackers intent on finding vulnerabilities in your installation.

The solution proposed here uses 7G Firewall, by Perishable Press, an .htaccess firewall with thousands of rules, and integrates it with Cloudflare. Typically, an .htaccess firewall will block requests right then and there. Here instead we are proposing that all malicious requests be redirected to special URLs that are subsequently blocked by Cloudflare.

The .htaccess Firewall

For the purpose of this solution, we have used the 7G Firewall. You should visit their website and download the code directly, as it is actively maintained and new versions are released every now and then.

There are, however, other .htaccess firewall solutions available, including some that are created by WordPress plugins. You should search and study them carefully, and decide by yourself which is the best server-side .htaccess firewall solution for your use case.

The 7G Firewall is comprised of six blocks, each containing .htaccess directives to protect against different types of bad requests. At the end of each block, there are two RewriteRule directives, of which only one can be active at any given time. For that reason, the second RewriteRule directive in each block is originally commented out (you change any .htaccess line into a comment by placing a # character before the directive). The second RewriteRule in each block is there to be used along with 7G Firewall’s own logging feature.

What we are going to do is comment out both RewriteRule directives and add a third one for the purpose of redirecting each bad request to a special URL, one that will be blocked by Cloudflare, and offer a hint of what was wrong with the request to begin with.

The first block has directives to block based on query strings (here you see the last two conditions).

RewriteCond %{QUERY_STRING} (union)(.*)(select)(.*)(\(|%28) [NC,OR]
RewriteCond %{QUERY_STRING} (concat|eval)(.*)(\(|%28) [NC]

RewriteRule .* - [F,L]
# RewriteRule .* /7G_log.php?log [END,NE,E=7G_QUERY_STRING:%1___%2___%3]

What we want to do is to change that, by inserting the redirecting directive:

RewriteCond %{QUERY_STRING} (union)(.*)(select)(.*)(\(|%28) [NC,OR]
RewriteCond %{QUERY_STRING} (concat|eval)(.*)(\(|%28) [NC]

# RewriteRule .* - [F,L]
RewriteRule .* /bad-request-QS [R,L]
# RewriteRule .* /7G_log.php?log [END,NE,E=7G_QUERY_STRING:%1___%2___%3]

In case you wonder, the [R,L] instruct the server to [R]edirect, and treat this as the [L]ast directive, stop processing the .htaccess any further.

For the first block of directives in the 7G Firewall, I called the path /bad-request-QS . Likewise, other blocks will be respectively redirected to their own URL path, so that we will have at the end 6 different paths, but all beginning with the same “/bad-request” string:

RewriteRule .* /bad-request-QS [R,L]
RewriteRule .* /bad-request-URI [R,L]
RewriteRule .* /bad-request-UA [R,L]
RewriteRule .* /bad-request-host [R,L]
RewriteRule .* /bad-request-referrer [R,L]
RewriteRule .* /bad-request-method [R,L]

The Cloudflare Firewall Rule

What we need to do next is to create a Cloudflare Firewall Rule that will block any request beginning with the /bad-request string. The expression can be as simple as (http.request.uri.path contains "/bad-request"), though you may want to also include a hostname to limit its application to, say, a testing subdomain, before fully implementing it across your domain. (Since these redirects will occur whether or not they are blocked by Cloudflare, you may want to create a minimalist 404 page to be served to your malicious visitors in case Cloudflare is temporarily off.)

After you implement the 7G Firewall with the RewriteRule directives to redirect bad requests, and the Cloudflare Firewall Rule to catch them, you are going to start seeing both firewalls in action on the Cloudflare Firewall Events Log (As I was trying to run bad requests to see this working, a bot out of Singapore gave me a hand, ha!)

As time goes by and you see lots of activities matching a given pattern, you may want to refine your general Cloudflare Firewall rules to make sure malicious requests are blocked at the cloud level. Having an .htaccess firewall doing a “last-mile” job greatly improves your ability to identify bad behavior.

One More .htaccess Tip

Why not use the same logic and redirect all 403 Forbidden errors out or your origin to Cloudflare Firewall?

All you need to do is adding the ErrorDocument directive at the top of your website’s .htaccess file:

# Send error 403 to a Cloudflare error page
ErrorDocument 403 https://example.com/bad-request

With that .htaccess command in place, any request that results in a 403 will also be redirected, and blocked by the same Cloudflare Firewall Rule above, giving you another hint that may help you refine your Cloudflare Firewall rules.

The goal is to have as much bad behavior blocked at the cloud as possible. An .htaccess firewall may help you along the way.