-
Notifications
You must be signed in to change notification settings - Fork 578
Description
What happened?
When HTTP/3 is enabled in BunkerWeb, ModSecurity does not receive any request header values (such as Host, :authority, or SERVER_NAME). Because these variables are empty, any custom ModSecurity rules or chains that rely on matching headers will fail to trigger.
For example, I was trying to write a custom rule to disable specific CRS checks for a GraphQL endpoint on a specific domain:
CUSTOM_CONF_MODSEC_CRS_graphql: |
SecRule REQUEST_FILENAME "@rx ^/api/graphql$" "id:12001,phase:1,nolog,ctl:ruleRemoveById=932100,chain"
SecRule REQUEST_HEADERS:Host "@rx ^example\.com$" "nolog"
This rule works perfectly under HTTP/2. However, under HTTP/3, the second chain check fails because REQUEST_HEADERS:Host has no value assigned to it.
While Nginx is clearly receiving and processing the HTTP/3 QUIC headers, it appears these headers are not being mapped to the ModSecurity request header variables during the handoff. Interestingly, REQUEST_FILENAME still populates correctly, but the headers do not.
How to reproduce?
Enable HTTP/3. Add a custom ModSecurity rule designed to log header variables to test the mapping. Here's what I used.
SecRule REQUEST_FILENAME "@rx ^/api/graphql$" \
"id:99999,phase:1,pass,log,msg:'Host=%{REQUEST_HEADERS.Host} Authority=%{REQUEST_HEADERS.:authority} Server=%{SERVER_NAME}'"Send request to https://example.com/api/graphql. Then check the BunkerWeb logs. You will see that the variables in the msg output are completely empty.
Failing Output (HTTP/3):
Host, Authority, and Server are completely empty inside the [msg "..."] block.
[warn] 3530#3530: *3019 ModSecurity: Warning. Matched "Operator `Rx' with parameter `^/api/graphql$' against variable `REQUEST_FILENAME' (Value: `/api/graphql' ) [msg "Host= Authority= Server="] [hostname "example.com"], server: example.com, request: "POST /api/graphql HTTP/3.0"
Expected/Working Output (HTTP/2):
The exact same rule correctly logs the variables.
[warn] 194#194: *143 ModSecurity: Warning. Matched "Operator `Rx' with parameter `^/api/graphql$' against variable `REQUEST_FILENAME' (Value: `/api/graphql' ) [msg "Host=example.com Authority= Server=example.com"] [hostname "example.com"], server: example.com, request: "POST /api/graphql HTTP/2.0"
Configuration file(s) (yaml or .env)
services:
bunkerweb:
image: bunkerity/bunkerweb:1.6.8
ports:
- "80:8080/tcp"
- "443:8443/tcp"
- "443:8443/udp"
environment:
<<: *bw-env
restart: "unless-stopped"
networks:
- bw-universe
- bw-services
bw-scheduler:
image: bunkerity/bunkerweb-scheduler:1.6.8
environment:
<<: *bw-env
BUNKERWEB_INSTANCES: "bunkerweb"
MULTISITE: "yes"
USE_WHITELIST: "yes"
SERVER_NAME: "example.com"
USE_REVERSE_PROXY: "yes"
REVERSE_PROXY_URL: "/"
AUTO_LETS_ENCRYPT: "yes"
SEND_ANONYMOUS_REPORT: "no"
SERVE_FILES: "no"
USE_CLIENT_CACHE: "yes"
USE_GZIP: "yes"
DISABLE_DEFAULT_SERVER: "yes"
USE_REDIS: "yes"
REDIS_HOST: "bw-redis"
USE_BROTLI: "yes"
USE_DNSBL: "yes"
API_ENABLED: "yes"
#--------------------------------------------
USE_MODSECURITY_GLOBAL_CRS: "yes"
# example.com
CUSTOM_CONF_MODSEC_CRS_graphql: |
SecRule REQUEST_FILENAME "@rx ^/api/graphql$" "id:12001,phase:1,nolog,ctl:ruleRemoveById=932100,chain"
SecRule REQUEST_HEADERS:Host "@rx ^example\.com$" "nolog"
example.com_REVERSE_PROXY_HOST: "http://172.17.0.1:5555"
restart: "unless-stopped"
networks:
- bw-db
- bw-universeBunkerWeb version
1.6.8
What integration are you using?
Docker
Linux distribution (if applicable)
Ubuntu Server 22.04
Removed private data
- I have removed all private data from the configuration file and the logs
Code of Conduct
- I agree to follow this project's Code of Conduct