3

In my Apache configuration file, I am currently blocking potentially malicious user agents using the following config:

SetEnvIfNoCase User-Agent "^\W" badagent
<Location />
    Deny from env=badagent
</Location>

This will deny all requests with a user agent that begins with anything except for a-Z or 0-9. A 403 Forbidden error is displayed.

I would like to change my configuration in order to be able to provide a different 403 ErrorDocument for different blocking reasons.

I am aware that it might not always be a good idea to tell somebody the exact security reason for their request being blocked, but this is just in case a legitimate user has their request blocked. I want them to know what the problem is instead of just seeing a standard 403. If somebody is attacking my site, they most likely know why their request is being blocked.

For example:

Request blocked due to malformed user agent.
Request blocked due to disallowed request method.
Request blocked due to hotlinking.

In order to do this, I must use If statements within my config:

<If "%{HTTP_USER_AGENT} == '^\W'">
    ErrorDocument 403 "403 Forbidden - Request blocked due to malformed user agent."
    Require all denied
</If>

My concern with this is that the HTTP_USER_AGENT variable could be used for command injection. I ran commix on an offline test server with this configuration and it did not detect anything, but I want to be sure.

I struggled to find any conclusive documentation on if/how Apache sanitizes variables from a HTTP request.

I am running a plain HTML/CSS website, no PHP or anything like that. Standard Apache installation with various hardening configurations and unneeded modules disabled.

Could the If statement used above be vulnerable to command injection, and if so, how do I protect against it?

  • Denying user-agents will avoid you some bulk traffic and perhaps actual attacks but you cannot rely on it to 'protect' your website. It is still a useful thing to do though, considering the amount of 'bad robot' traffic (https://access.watch/database). Now, I guess `%{HTTP_USER_AGENT}` has some checks done as it is meant to be used like you do without any checking, _I believe_ (but have no doc for you - check the source code!). Finally, note that sqlmap, for instance, has a default user agent `sqlmap-` _(and it can easily be changed)_. As a general security rule, use defined **whitelists**. – Bamse Mar 28 '17 at 14:32
  • As you said, providing the error might not be a good choice. If you want to provide something a bit more verbose, I would advise you to get a staging server where you don't have to consider such interactions that might be unsure. – M'vy Mar 28 '17 at 14:35

1 Answers1

2

You are trying to protect your web application via Apache, but instead, the proper way to protect your apache/web-application is to make sure that attackers are denied access at lower level of OSI model. For example you can use fail2ban which protects on OSI level 3 (Network) thru iptables, as it bans entire IP address.

enter image description here

Apache is OSI level 7 (application).

So instead of having

<If "%{HTTP_USER_AGENT} == '^\W'">
    ErrorDocument 403 "403 Forbidden - Request blocked due to malformed user agent."
    Require all denied
</If>

in your config, you should rather create custom log file by adding

LogFormat "%a %{User-agent}i" ipagent

And

CustomLog /var/log/apache2/useragent.log ipagent

And proceed with fail2ban config as explained at answer given here https://serverfault.com/questions/251988/blocking-apache-access-via-user-agent-string

Aditionally to further harden your server, make sure to install apache's mod_security with OWASP rules, to do it, check my answer, given here: Some bot keeps posting this to my server