Skip to content

Conversation

@AMoo-Miki
Copy link

ModSecurity cannot see the Host header in HTTP/3 requests because HTTP/3 uses the :authority pseudo-header, which nginx parses into r->headers_in.server but doesn't add to the headers list.

This commit:

  • Adds NGX_HTTP_VERSION_30 case to http_version switch
  • Manually extracts Host from r->headers_in.server for HTTP/3 requests
  • Adds Host header to ModSecurity transaction before processing other headers

Fixes #305 false positives from OWASP CRS rule 920280 (Missing Host Header) on HTTP/3 connections.

Tested with nginx 1.29.3 and ModSecurity 3.0.13.

@airween
Copy link
Member

airween commented Dec 8, 2025

Hi @AMoo-Miki,

first of all, thank you for your PR.

I am sure that this is a very important step towards being able to handle HTTP/3 requests. But I'm not sure this is the right way.

Please do not misunderstand me, I don't want to reject this PR, but I think we need to discuss how can we handle HTTP/3 headers correctly.

I think adding a header with the name Host so that it is not the host header is not accurate and might be misleading. I mean in case of HTTP/3, the header authority should be added as authority - but I'm not sure that, this is why I think we should discuss that.

Also, please add some tests to this new feature.

@AMoo-Miki
Copy link
Author

AMoo-Miki commented Jan 27, 2026

@airween thanks for looking into this.

I totally get where you are coming from but if I put my "salesman hat" on, I could say adding it as a "Host" header here isn't really fabricating data; it's exposing the same value to ModSecurity's REQUEST_HEADERS collection so that rules checking REQUEST_HEADERS:Host (like CRS 920280) work correctly.

Here are some other options I considered:

  1. Create a fake header called "Authority" in the connector because NGINX hands :authority in r->headers_in.server and not headers. This is a bad idea because it is not a standard key and can conflict or be confused with actual headers in the request. Additionally, all rules that check for Host will need to be updated to check for Authority too.
  2. Create msc_set_request_authority in ModSecurity which would populate REQUEST_HEADERS:Host. This would add complications because the lib would have to deal with the possibility of conflicting Host headers.
  3. Create msc_set_request_authority in ModSecurity which would populate REQUEST_AUTHORITY but then every existing rule that checks for REQUEST_HEADERS:Host would need to be updated to also check REQUEST_AUTHORITY.
  4. Similar to 3 but on a larger scale: introduce the concept of pseudo-headers in ModSecurity; this would the future-safe thing to do but is a substantial undertaking. However, this wouldn't help this connector as NGINX translates other pseudo-headers to request props already.

What really helped me choose was RFC 9114, Section 4.3.1:

An intermediary that converts an HTTP/3 request to HTTP/1.1 MUST create a Host field if one is not present in a request by copying the value of the :authority pseudo-header field.

I interpreted that as it being necessary for this connector to populate Host with :authority when it is missing. You might notice that my change doesn't "waste" time checking if Host header is missing; this is because if it somehow does exist, the next block will overwrite it when calling msc_add_n_request_header() for the actual headers -- Lemme know if you object.

This approach ensures consistent behavior across HTTP/1.1, HTTP/2, and HTTP/3 without requiring rule modifications.

PS, working on adding tests.
Added tests.

@AMoo-Miki AMoo-Miki force-pushed the fix-http3-host-header branch from 92c9e6b to 6abcc17 Compare January 27, 2026 09:16
ModSecurity cannot see the Host header in HTTP/3 requests because HTTP/3 uses the `:authority` pseudo-header, which nginx parses into `r->headers_in.server` but doesn't add to the headers list.

This commit:
- Adds `NGX_HTTP_VERSION_30` case to `http_version` switch
- Manually extracts Host from `r->headers_in.server` for HTTP/3 requests
- Adds Host header to ModSecurity transaction before processing other headers

Fixes owasp-modsecurity#305 false positives from OWASP CRS rule 920280 (Missing Host Header) on HTTP/3 connections.

Tested with nginx 1.29.3 and ModSecurity 3.0.13.
@AMoo-Miki AMoo-Miki force-pushed the fix-http3-host-header branch from 6abcc17 to b95a97c Compare January 27, 2026 10:49
@sonarqubecloud
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

'Host' header missing when HTTP3 is in use prevents "SecRule REQUEST_HEADERS:Host" rules from being effective.

2 participants