'How do I create a rule to block all user agents with ModSecurity V3?
I want to add a custom ModSecurity (V3) rule that can block all user agents, and allow me to whitelist certain User Agents from a file.
If this is possible, if someone could share the rule with me, that would be great. I cannot seem to figure out the rule to do this.
Thanks!
Solution 1:[1]
This is a bit dangerous what you want to do, but I try to give you some help.
I think CRS rule 913100 would be a good point to start for you.
It's a bit complex if you new in ModSecurity any SecLang, so in short, this would be a possible solution. Create a rule for your WAF, like this:
SecRule REQUEST_HEADERS:User-Agent "!@pmFromFile allowed-user-agents.data" \
"id:9013100,\
phase:1,\
deny,\
t:none,\
msg:'Found User-Agent associated with security scanner',\
logdata:'Matched Data: illegal UA found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}'"
Please note, that you can choose any id
for your rule what you want, but there is a reservation list for id's:
https://coreruleset.org/docs/rules/ruleid/#id-reservations
It's highly recommended you choose a right one to avoid the collision with other rules. 9013100 would be a good choice, and it represents where this rule is derived from.
Then you have to make a file with a list of your allowed user agents. Note, that you have to place that list in same directory as the rule conf file exists. The name of file must be (as you can see above) allowed-user-agents.data
. You can put an agent per line. Also you can use comments with #
at the beginning of the rule - just see the CRS's data file.
How this rule works?
SecRule
is a token which tells the engine that this is a rule. REQUEST_HEADERS
is a collection (a special variable), what the engine expands from the HTTP request. The :
after the name indicates that you want to investigate only the mentioned header, namely User-Agent
.
The next block is the operator. As documentation says @pmFromFile "Performs a case-insensitive match of the provided phrases against the desired input value.". This is what you need exactly. There is a !
sign before the operator. This inverts the operator's behavior, so it will be TRUE if the User-Agent isn't there in the file.
The next section is the action's list. id
is mandatory, this identifies the rule. phase:1
is optional but very recommended to place one. For more information, see the reference. deny
is a disruptive action, it terminates the request immediately. msg
will append a message to the log in every cases. logdata
will show a detailed info about the rule result.
Why is this a little dangerous
As you can see in the documentation of @pmFromFile
operator, it uses patterns. This means you do not have to place the exact User-Agent names, it's enough to put a pattern, like "curl", or "mozilla" - but be careful, a wrong pattern can lead to false positive results, which means - in this case - an attacker can bypass your rule: it's enough to place the pattern to trick it.
Consider you put the pattern my-user-agent
into the data file. Now if someone just uses this pattern as User-Agent, the rule won't match.
It is generally true that handling whitelists in this way (in some special contexts, like this) is dangerous, because it's easy to bypass them.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |