Description
Describe the bug
Libmodsecurity3 produces log (through a callback function eg. for Nginx) with unusable [hostname]
field. [hostname]
always contains the IP address of the server, which has no informational value.
Logs and dumps
An example:
ModSecurity: Warning. detected SQLi using libinjection. [file "/usr/share/modsecurity-crs/rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf"] [line "46"] [id "942100"] ... [tag "PCI/6.5.2"] [hostname "18.19.20.21"] [uri "/xmlrpc.php"]... client: 91.92.93.94, server: www.myserver.com, request: "POST /xmlrpc.php HTTP/1.1", host: "www.myserver.com"
As you can see, the log contains the server
and host
fields at the end of the line, but unfortunately the length of the line is limited (it's hard coded in Nginx to 2048 bytes), and if the request is too long (eg. there is a GET
request with some very long query string) these fields will be disappeared.
To Reproduce
Send any invalid request that triggers a rule and produces a log entry.
Expected behavior
As in case of Apache's mod_security2 module, it would be fine to get the hostname
field with the correct value.
Server (please complete the following information):
- ModSecurity version (and connector): libmodsecurity3, all versions
Additional context
There is a previous intention to fix this issue:
but it was rejected (see the discussion). The first point was this:
The 'Host' header is untrusted user input. - which is a bit interesting, because (meanwhile I reviewed the code again) I found that the variable SERVER_NAME
(reference) is also produced from the Host
header - see the source - without any filtering.
Never mind, I would like to discuss how can we solve this issue.
My suggestions:
- send that PR again (note: Apache also follows the implemented way)
- forget that PR and the host name, and add a new function to libmodsecurity3's API which provides the possibility to set the host name for the application who embeds it
- for this, I created a separated branch: https://github.com/owasp-modsecurity/ModSecurity/compare/v3/master...airween:ModSecurity:v3/sethostname?expand=1
- a brief summary: this fix provides a new function:
setRequestHostName()
(andmsc_set_request_hostname()
in C) that sets the inside variable - if the application does not call this, the value of the variable is the same as the server IP (nothing changes)
- if the application calls it, then it can sets the correct hostname
I also created a patch for Nginx connector, here is the result:
curl -v -H "Host: modsecurity.org" http://localhost/?q=/bin/bash
the log:
ModSecurity: Warning. Matched "Operator `ValidateByteRange' ... [tag "capec/1000/210/272"] [hostname "modsecurity.org"] [uri "/"] ... client: ::1, server: _, request: "GET /?q=/bin/bash HTTP/1.1", host: "modsecurity.org"
Note, that the connector uses Nginx's r->headers_in.server
variable, see Nginx's source.
Please share your idea about this behavior and possible solutions.