Skip to content

Duplicate Server headers in Audit Log when using more_set_headers or more_clear_headers in Nginx #3368

Open
@wRkA

Description

@wRkA

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:

  1. Configure the nginx.conf file using either:

    • more_clear_headers Server;
    • more_set_headers 'Server: Custom Name';

    Each directive was tested separately (never together).

  2. Test the configuration:

    nginx -t
  3. Reload Nginx:

    nginx -s reload
  4. 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):


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!

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.xRelated to ModSecurity version 3.x

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions