WordPress hosting and the BitNinja WAF: How to do it right? – (Part 2)

Last time we finished off with the advice that if you’re hosting mainly WordPress websites, you should only enable the BitNinja Safe Minimum ruleset for the “/” location or any other domain pattern that contains “/wp-admin”.

So let’s talk a bit more about domain patterns

With the BitNinja WAF, we’d like to give you the opportunity to customize your firewall rules with domain patterns (we also call them location patterns, because they are, in fact, nginx location patterns or directives). It’s similar to virtual hosts defined on a web server.

Let’s say that you have multiple domains on your server, each of these are WordPress websites’ domains.

  • very-cool-ninjas.com

  • example.com

Since these are WordPress installs, they have an administration dashboard under the http(s)://very-cool-ninjas.com/wp-admin and http(s)://www.example.com/wp-admin location.

Let’s continue the example with the very-cool-ninjas.com domain 🙂

If a user is trying to edit their WordPress website, she or he will try to access the following URL from their browser: http(s)://very-cool-ninjas.com/wp-admin to add or edit posts, manage users or comments, edit products in the webshop, manage orders, and so on. These editing actions could appear as XSS attacks if the stricter WAF rules are enabled. That’s why it’s not advised to enable the BitNinja medium or strict ruleset template there, because it could end up with innocent users getting greylisted, and more complaints to you, the server owner.

The important part is, you can customize WAF rules for every domain pattern.

You can use certain wildcard characters in these patterns. The asterisk “*” means any character, so for example:    */wp-admin/*     will match the following URLs:




But not this: https://very-cool-ninjas.com/wp-login.php

Additional options: Disable WAF and Lock down

You can use domain patterns to tell the WAF module not to check specific locations at all, by adding the pattern and clicking on the Disable WAF option on the Dashboard. Generally, it is not advised to use this option. So why is it there?

Unfortunately, there can be poorly-written websites on your server which will generate a lot of WAF incidents that are false positives, and thus a lot of user complaints could come regarding these domains. When you don’t have the capacity to check carefully which rules are causing the problems, you can decide to disable the WAF for that domain, thus excluding these domains from our firewall checks.

There is also a Lock down option for location patterns, that you can use if necessary. Using this option and “locking down” a domain, you can make a website read-only: meaning that it will be available for visitors, but no user registration, no blog or forum post, no editing will be available at that domain at all. All POST requests for this domain will be blocked by the WAF, but the GET requests will still reach the web server. If the website is under attack and is spammed with POST requests, the attacks will continue, but won’t reach the web-server – the WAF will drop the request. If there is a backdoor in one of the folders of the website, the backdoor’s owner won’t be able to access it. But if the attacks continue, no incidents will be generated, and we can’t greylist the malicious IP address.

This is a really aggressive way to protect a website and is only treating the symptoms and not the disease, so I advise that you only use it as a last resort, if there’s really no other option available.

So how did we define the BitNinja safe minimum ruleset?

We must tell you, while we were designing, implementing and testing the new BitNinja WAF with mod_security and the OWASP Core Rule Set (CRS), we invested a lot of time in testing the different rules. We wanted to provide our customers WAF rules that generate a very low false-positive rate.

We started with the OWASP CRS’s low false positive rated rules, which consists of more than 90 firewall rules. We carefully tested all these rules on our own test servers for months, and later continued with the alpha and beta tests. When we’ve finished testing and successfully created the BitNinja safe minimum ruleset template – that became the base of protection for the WAF with the least false positives -, only 16 rules remained.

We classified the majority of OWASP CRS rules in our stricter ruleset templates, and this is mainly because of the WordPress CMS engine.

Just to tell you one example: the rule number 921110, called HTTP Request Smuggling, looks for a CR/LF character, that is followed by a HTTP/WEBDAV method name. It should rule out malicious HTTP request smuggling attempts.

But then WordPress comes into play, and one WP user will generate the following request, that gets caught by the WAF rule 921110:

The reason for this editing attempt getting caught is because the following regex got triggered with the data that arrived in the POST request:



Post data:


[This content has been modified for privacy purposes.]

If this text makes no sense to you, it’s okay, just copy and paste it to an online URL decoder service’s input, and hit the decode button.

In this case, the regex caught the following expression: %0Aget+yourself+a+dog

The %0A is the URL decoded variant of the line feed (LF) character. This got followed by the word “get”, which could indicate a HTTP GET request smuggling attack. It can also happen with the words “post”, “put” and so on, as seen in the regular expression above.

WordPress handles user input this way, so we need to remove these kind of rules from the BitNinja safe minimum ruleset template, to prevent false positives.

What would you like to read about next? Please write us in the comments below!

Stay safe!

Also, check out the other parts:

Part 1: for the basics

Part 3:  for the safe minimum ruleset