Rejecting a request with any query string

I recently switched to HAProxy 3.0.11 (-9e587df) on a OpenBSD System, version 7.7. I use HA to switch between hosts but most importantly also to filter out bad traffic. Most of it works fine: Requests that are for sure with bad intent lead to a TCP reject. Among those are also request with query parameters, example “GET /?dns…” but also things like “GET /?@zdi/Powershell”. Problem is that a few of these requests still get through. When I send them with my browser, HA rejects (closes) the connection immediately. I have not understood how these requests still make their way to my servers. I reject if “?” follows “/” (the web root) or “/index.html”

Part of my configuration:

acl defpath path / /index.html

acl qstr query -m found

tcp-request inspect-delay 10s

tcp-request content reject if qstr defpat

Rest is not of importance, just the usual stuff and a few acl to reject if somebody probes for example for Wordpress or “admin” etc.

The complete configuration is required here.

The configuration snippet you have shown cannot work after 10 seconds after connection establishment, it probably cannot work for subsequent request in a keepalive session, but this depends on the rest of the configuration.

Does haproxy reject the TCP sessions when the second requests hits in a keepalive session, like:

curl -vv "http://haproxy.srv/validrequest" "http://haproxy.srv/?@zdi/Powershell" 

Hello Lukas!

Thank yo very much for the quick response and the advice, appreciated! I put the HAProxy configuration in a file (only modified the domain name, rest unchanged), the result of the curl test (domain name changed and body of html response removed) and an extract of an access log. I share this file as it is more than 300 lines long. The tests show that in the majority of the cases bad requests are rejected (curl, browser and programs). What I will do is keeping the log files of HAProxy, I have sent them to Nirvana as they tend to become quite big. Or start HAProxy with nohup in a terminal session. I did that in the past but as I said, only few bad requests get through :slight_smile:

Thank you again and Best Regards

Steven

The link to the text file:

https://mega.nz/file/9G4UiJhJ#DL_4rUJlPxfLirv1pSiILsZGMGMD59YNeK6p24WCJlQ

The definition of the path variable in haproxy is:

This extracts the request’s URL path, which starts at the first slash and ends before the question mark (without the host part).

You should use the pathq variable instead, so you can match the question mark as well:

acl probe pathq -m beg /. /: /_ /~ /? /% /admin /wp /cgi-bin /index.html?

This way I think you should be able to simplify your configuration a lot.

However due to the mixed results you seem to be getting, I think you may have haproxy instances with older configurations running in the background in parallel, that sometimes catch a requests and because they run an older configuration, the request is not rejected.

To make sure: stop haproxy ordinarily and then manually kill all remaining haproxy processes (killall haproxy). Only when no haproxy processes are around anymore, you start haproxy again.

You should not need tcp-request inspect-delay because you are in HTTP mode with full HTTP parsing.

If things still don’t work reliably, try putting http request deny rules after the tcp-content reject rules, to see if haproxy would emit a 403:

http-request deny if qstr defpat
http-request deny if probe !wellkn

Hello Lukas!

My bad! The logs revealed what I simply overlooked. A request with a non-existing path that is followed by queries of course gets routed through, but in the web server log I did not see the original request as it was rewritten (path contained “teorema505” = Qakbot related attack). So there was a path in front of the “?”. The proxy works exactly as configured. I now know how to continue from here. The discussion helped me to look a bit further, thank you again.

I will simplify the configuration as you suggested, makes it much clearer and also easier to spot what I overlooked.

Best regards

Steven

1 Like