Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions images/router/haproxy/conf/haproxy-config.template
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,23 @@ frontend public
# Strip off Proxy headers to prevent HTTpoxy (https://httpoxy.org/)
http-request del-header Proxy

# Strip off X-SSL* headers for plain HTTP if not explicitly disabled.
# This prevents unauthenticated spoofing of mutual TLS client identities.
{{- if isTrue (env "ROUTER_MUTUAL_TLS_HEADER_FILTER" "true") }}
http-request del-header X-SSL
http-request del-header X-SSL-Client-CN
http-request del-header X-SSL-Client-DER
http-request del-header X-SSL-Client-DN
http-request del-header X-SSL-Client-NotAfter
http-request del-header X-SSL-Client-NotBefore
http-request del-header X-SSL-Client-SHA1
http-request del-header X-SSL-Client-Serial
http-request del-header X-SSL-Client-Subject
http-request del-header X-SSL-Client-Verify
http-request del-header X-SSL-Client-Version
http-request del-header X-SSL-Issuer
{{- end }}
Comment on lines +228 to +243

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Keep the filter enabled on malformed env values.

isTrue(env(..., "true")) is only secure-by-default when the variable is unset. If ROUTER_MUTUAL_TLS_HEADER_FILTER is set to any non-empty typo, env() returns that value and isTrue() falls back to false, which silently disables the CVE mitigation without an explicit opt-out.

Suggested fix
-  {{- if isTrue (env "ROUTER_MUTUAL_TLS_HEADER_FILTER" "true") }}
+  {{- $mtlsHeaderFilter := firstMatch "(?i:true|false)" (env "ROUTER_MUTUAL_TLS_HEADER_FILTER") "true" }}
+  {{- if isTrue $mtlsHeaderFilter }}

Also applies to: 341-357, 453-469

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@images/router/haproxy/conf/haproxy-config.template` around lines 228 - 243,
The mutual-TLS header stripping in the haproxy-config.template blocks is only
enabled when isTrue(env(..., "true")) evaluates true, which can silently disable
the mitigation for malformed non-empty values. Update the
ROUTER_MUTUAL_TLS_HEADER_FILTER check so the filter stays enabled by default
unless the variable is explicitly set to a recognized false value, and reuse the
same logic in the other matching header-filter sections to keep behavior
consistent.


# DNS labels are case insensitive (RFC 4343), we need to convert the hostname into lowercase
# before matching, or any requests containing uppercase characters will never match.
http-request set-header Host %[req.hdr(Host),lower]
Expand Down Expand Up @@ -321,6 +338,24 @@ frontend fe_sni
# Strip off Proxy headers to prevent HTTpoxy (https://httpoxy.org/)
http-request del-header Proxy

# Strip off X-SSL* headers if not explicitly disabled.
# This prevents unauthenticated spoofing of mutual TLS client identities
# when mutual TLS is not enabled and so the headers are not set below.
{{- if isTrue (env "ROUTER_MUTUAL_TLS_HEADER_FILTER" "true") }}
http-request del-header X-SSL
http-request del-header X-SSL-Client-CN
http-request del-header X-SSL-Client-DER
http-request del-header X-SSL-Client-DN
http-request del-header X-SSL-Client-NotAfter
http-request del-header X-SSL-Client-NotBefore
http-request del-header X-SSL-Client-SHA1
http-request del-header X-SSL-Client-Serial
http-request del-header X-SSL-Client-Subject
http-request del-header X-SSL-Client-Verify
http-request del-header X-SSL-Client-Version
http-request del-header X-SSL-Issuer
{{- end }}

# DNS labels are case insensitive (RFC 4343), we need to convert the hostname into lowercase
# before matching, or any requests containing uppercase characters will never match.
http-request set-header Host %[req.hdr(Host),lower]
Expand Down Expand Up @@ -415,6 +450,24 @@ frontend fe_no_sni
# Strip off Proxy headers to prevent HTTpoxy (https://httpoxy.org/)
http-request del-header Proxy

# Strip off X-SSL* headers if not explicitly disabled.
# This prevents unauthenticated spoofing of mutual TLS client identities
# when mutual TLS is not enabled and so the headers are not set below.
{{- if isTrue (env "ROUTER_MUTUAL_TLS_HEADER_FILTER" "true") }}
http-request del-header X-SSL
http-request del-header X-SSL-Client-CN
http-request del-header X-SSL-Client-DER
http-request del-header X-SSL-Client-DN
http-request del-header X-SSL-Client-NotAfter
http-request del-header X-SSL-Client-NotBefore
http-request del-header X-SSL-Client-SHA1
http-request del-header X-SSL-Client-Serial
http-request del-header X-SSL-Client-Subject
http-request del-header X-SSL-Client-Verify
http-request del-header X-SSL-Client-Version
http-request del-header X-SSL-Issuer
{{- end }}

# DNS labels are case insensitive (RFC 4343), we need to convert the hostname into lowercase
# before matching, or any requests containing uppercase characters will never match.
http-request set-header Host %[req.hdr(Host),lower]
Expand Down