owasp-modsecurity / owasp-modsecurity/ModSecurity

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

Open
#3,368 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

3.x
Dominant language
C++
Stars
9.8k
Forks
1.8k
Avg merge
2h 46m
Merged PRs (30d)
1

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:

  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!

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the nginx.conf configurations using more_set_headers or more_clear_headers, then reproduce with nginx -t, nginx -s reload, and the supplied curl request. Trace the response-header audit logging path for the F section; done means each configuration records the Server header once, matching the baseline audit log.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, nginx
Domain
security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.