There's no magic bullet here, if you are blocking "bad bots" based on the User-Agent string then you need to match on a sufficiently unique substring as to not conflict with other bots and users.
But will such an approach unintentionally block good ones as well?
Not if you've chosen a sufficiently unique substring to match against.
HOWEVER, "bad bots" can be bad in their very nature. They can pretend to be "good bots", they can pretend to be normal users and use a common browser User-Agent string. These "bad bots" cannot be blocked based on the User-Agent string, since there is nothing in the User-Agent that differentiates them.
In fact, the "really bad bots" probably can't be simply blocked by their User-Agent
string - that would be too easy!
say in the future a search engine like Google decides to include one of my blocked strings in some random part of the user-agent
In that case:
You made a bad choice in what substring you used to base your block on.
Google was naive in using a common string used by other (bad) bots. (Unlikely)
Is there some kind of regulatory authority that will oversee and prevent overlap of strings among different user agents?
No. Preventing overlap is purely down to the developer. Sometimes "overlap" can be intentional (and sometimes in a bad way). eg. There are probably a million and 1 Googlebot
User-Agents out there that are not actually Googlebot. (In order to detect real Googlebots you need to do a reverse lookup on the IP address.)
Anyone can write a bot with anything in the User-Agent string.
Anyone can customise the User-Agent string when making an HTTP request - it is just an HTTP request header. (In fact, this is often standard practice when website testing.)
Or will you recommend to include the full or at least more specific strings for user agents?
Whatever is required.
Bear in mind that with SetEnvIf[NoCase]
you are supplying a regex and matching the entire User-Agent using a regex can be a bit messy and it's easy to make a mistake. If you block the whole User-Agent, use a comparison that allows you to pass in an ordinary string.
For example, you can use the =
prefix operator on the CondPattern in a mod_rewrite RewriteCond
directive to match a literal string.
# Check entire User-Agent header and set bad_bot if matched
RewriteCond %{HTTP_USER_AGENT} "=<full user agent string goes here exactly as written>" [OR]
RewriteCond %{HTTP_USER_AGENT} "=<another user agent to block>"
RewriteRule ^ - [E=bad_bot:1]
SetEnvIfNoCase User-Agent .*abcbot.* bad_bot
User-Agent strings are often a specific case, so should be matched cased-sensitively. So SetEnvIf
would be more appropriate most of the time. eg. If you see a User-Agent
that contains "GoogleBot" then it's most certainly a bad bot. Obviously, this can vary.
And note that the regex .*abcbot.*
is the same as simply abcbot
.