Skip to content

fix: preserve v5 proxy identity after hop header stripping - #3200

Merged
vishr merged 1 commit into
masterfrom
security/v5-proxy-derived-identity
Oct 30, 2026
Merged

vishr merged 1 commit into
masterfrom
security/v5-proxy-derived-identity

Conversation

@vishr

@vishr vishr commented Oct 30, 2026 •

Copy link
Copy Markdown
Member

Summary

 Proxy
   derive client identity once before retries
-  set X-Real-IP only before ReverseProxy strips hop-by-hop headers
+  also restore that identity immediately before the upstream RoundTrip

Port the proxy identity protection from v4 #3197 to v5. A client can otherwise use Connection: X-Real-IP to make released v5.4.3 omit the derived upstream identity header. An upstream that falls back to an untrusted forwarded header may then select an attacker-controlled identity. This patch preserves the derived value across HTTP requests, WebSocket upgrades, retries, and balancer request replacement.

v5 already uses the connection peer by default. This change preserves configured extractors, custom/default transports, existing XFF behavior, public APIs, dependencies, and the minimum Go version. The outbound request is cloned before its header is changed, respecting the RoundTripper contract.

Evidence

  • Before: New regressions fail on mixed-case/duplicate Connection nominations, a raw WebSocket upgrade, and a request-swapping retry path. A separate probe against the published v5.4.3 module reproduces the absent upstream header.
    After: The same regressions pass with the ported fix.
  • Full race tests pass on Go 1.25.0 and 1.27.3; vet, staticcheck, and golint pass. Govulncheck reports no vulnerabilities.
  • Permanent tests cover default/custom transports and extractors, duplicate X-Real-IP values, raw WebSocket negotiation, retries, and exactly one stateful extractor evaluation.
  • Fresh Claude review found no merge blockers on 07c2039. Claude independently ran vet, the full race suite, repeated new regressions, negative checks on base, and transport/cancellation/trailer probes. All three regression tests fail on base.
  • Claude confirmed the demonstrated v5 impact is header removal, with backend-dependent consequences; it found no basis to expand the original default-IP CVE ranges. Existing Connection-nominated removal of X-Forwarded-Proto remains a separate nonblocking follow-up. GitHub platform checks run on this PR.

Merge Danger

Door: two-way

Blast Radius: Proxy

Upstream X-Real-IP remains present even when a client nominates it as hop-by-hop. Each RoundTrip adds a request/header clone. No new client-IP migration is required for v5; its direct-peer default is unchanged.

@vishr
vishr merged commit b118d3d into master Oct 30, 2026
11 checks passed
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.

1 participant