Description
Describe the bug
Hi, the Audit Log duplicates the Server
header content under the Response headers
section F
.
When configuring Nginx with the following directives, the Audit Log duplicates the Server
header as shown.
Options that trigger the issue:
more_clear_headers Server;
more_set_headers 'Server: Custom Name';
First case (more_set_headers 'Server: Custom Name';)
Nginx configuration:
# Other options...
keepalive_timeout 15;
send_timeout 10;
more_set_headers 'Server: Custom Name'; # This option causes the duplicate response header.
proxy_hide_header X-Powered-By;
# Other options...
Logs and dumps: Audit Log
---Bo5kPrA4---A--
[30/Apr/2025:03:37:24 -0600] 174600584494.932607 192.168.1.35 41310 192.168.1.35 80
---Bo5kPrA4---B--
GET /?foo=/etc/passwd&bar=/bin/sh HTTP/1.1
Host: domain.host.sh
User-Agent: curl/8.5.0
Accept: */*
---Bo5kPrA4---D--
---Bo5kPrA4---E--
<html>\x0d\x0a<head><title>403 Forbidden</title></head>\x0d\x0a<body>\x0d\x0a<center><h1>403 Forbidden</h1></center>\x0d\x0a<hr><center>nginx</center>\x0d\x0a</body>\x0d\x0a</html>\x0d\x0a
---Bo5kPrA4---F--
HTTP/1.1 403
Server: Custom Name # Duplicate header.
Server: Custom Name # Duplicate header.
Date: Wed, 30 Apr 2025 09:37:24 GMT
Content-Length: 146
Content-Type: text/html
Connection: keep-alive
Second case (more_clear_headers Server;)
Nginx configuration:
# Other options...
keepalive_timeout 15;
send_timeout 10;
more_clear_headers Server; # This option causes the duplicate response header.
proxy_hide_header X-Powered-By;
# Other options...
Logs and dumps: Audit Log
---71j15QKX---A--
[30/Apr/2025:03:25:40 -0600] 174600514087.352175 192.168.1.35 39024 192.168.1.35 80
---71j15QKX---B--
GET /?foo=/etc/passwd&bar=/bin/sh HTTP/1.1
Host: domain.host.sh
User-Agent: curl/8.5.0
Accept: */*
---71j15QKX---D--
---71j15QKX---E--
<html>\x0d\x0a<head><title>403 Forbidden</title></head>\x0d\x0a<body>\x0d\x0a<center><h1>403 Forbidden</h1></center>\x0d\x0a<hr><center>nginx</center>\x0d\x0a</body>\x0d\x0a</html>\x0d\x0a
---71j15QKX---F--
HTTP/1.1 403
Server: # Duplicate header.
Server: # Duplicate header.
Date: Wed, 30 Apr 2025 09:25:40 GMT
Content-Length: 146
Content-Type: text/html
Connection: keep-alive
Final case (baseline without header modification)
Nginx configuration:
# Other options...
keepalive_timeout 15;
send_timeout 10;
# Other options...
Logs and dumps: Audit Log
---qfTAvG5v---A--
[30/Apr/2025:03:30:38 -0600] 174600543867.582044 192.168.1.35 36722 192.168.1.35 80
---qfTAvG5v---B--
GET /?foo=/etc/passwd&bar=/bin/sh HTTP/1.1
Host: domain.host.sh
User-Agent: curl/8.5.0
Accept: */*
---qfTAvG5v---D--
---qfTAvG5v---E--
<html>\x0d\x0a<head><title>403 Forbidden</title></head>\x0d\x0a<body>\x0d\x0a<center><h1>403 Forbidden</h1></center>\x0d\x0a<hr><center>nginx</center>\x0d\x0a</body>\x0d\x0a</html>\x0d\x0a
---qfTAvG5v---F--
HTTP/1.1 403
Server: nginx # Correct.
Date: Wed, 30 Apr 2025 09:30:38 GMT
Content-Length: 146
Content-Type: text/html
Connection: keep-alive
To Reproduce
Steps to reproduce the behavior:
-
Configure the
nginx.conf
file using either:more_clear_headers Server;
more_set_headers 'Server: Custom Name';
Each directive was tested separately (never together).
-
Test the configuration:
nginx -t
-
Reload Nginx:
nginx -s reload
-
Send a request to trigger the rule:
curl 'http://domain.host.sh/?foo=/etc/passwd&bar=/bin/sh'
Expected behavior
The expected behavior is that ModSecurity's Audit Log should not duplicate the Server
response header when using either more_clear_headers Server;
or more_set_headers 'Server: Custom Name';
.
Server (please complete the following information):
- ModSecurity v3.0.14 with nginx-connector v1.0.3
- WebServer: nginx/1.28.0
- OS: Ubuntu 24.04.2 LTS
Rule Set (please complete the following information):
- OWASP CRS v4.13.0
Additional context
After successfully compiling ModSecurity v3.0.14 with:
./configure --with-pcre2
I created the following directory structure:
/usr/local/modsecurity/etc
/usr/local/modsecurity/var
/usr/local/modsecurity/var/audit
/usr/local/modsecurity/var/data
/usr/local/modsecurity/var/log
/usr/local/modsecurity/var/tmp
/usr/local/modsecurity/var/upload
I then assigned appropriate ownership and permissions to each directory.
Following that, I applied the following configuration to ModSecurity:
SecRuleEngine On
SecPcreMatchLimit 150000
SecPcreMatchLimitRecursion 150000
SecResponseBodyAccess Off
SecTmpDir /usr/local/modsecurity/var/tmp/
SecDataDir /usr/local/modsecurity/var/data/
SecUploadDir /usr/local/modsecurity/var/upload/
SecUploadKeepFiles Off
SecUploadFileMode 0600
SecDebugLog /usr/local/modsecurity/var/log/debug.log
SecDebugLogLevel 3
SecAuditLog /usr/local/modsecurity/var/log/audit.log
SecAuditLogStorageDir /usr/local/modsecurity/var/audit/
I then compiled ModSecurity-nginx v1.0.3 with:
./configure --with-compat --with-http_ssl_module --add-dynamic-module=../modsecurity-nginx-v1.0.3
After several additional steps to load the necessary libraries, configure settings, and complete the setup, I installed the latest version of the OWASP Core Rule Set (CRS).
While testing the configuration and writing custom rules for my application, I noticed an issue when inspecting the Audit Logs. Specifically, when experimenting with Response headers in Nginx, I observed the Server header being duplicated.
I understand that not all of this information may be essential, but I wanted to provide as much detail as possible. I hope this helps clarify the context of the issue.
Thanks!