Add proxy.protocol.accepted.ip.range config to guard PROXY protocol data by peer IP#668
Open
Hritwik Singhai (devhritwik) wants to merge 2 commits intomasterfrom
Open
Add proxy.protocol.accepted.ip.range config to guard PROXY protocol data by peer IP#668Hritwik Singhai (devhritwik) wants to merge 2 commits intomasterfrom
Hritwik Singhai (devhritwik) wants to merge 2 commits intomasterfrom
Conversation
Copilot started reviewing on behalf of
Hritwik Singhai (devhritwik)
March 11, 2026 18:00
View session
6d2afda to
3009565
Compare
There was a problem hiding this comment.
Pull request overview
This PR introduces a per-listener guard for Jetty PROXY protocol handling in rest-utils to prevent client IP spoofing during v3/v4 migration scenarios where both non-PROXY and PROXY-capable frontends coexist.
Changes:
- Add
proxy.protocol.accepted.ip.rangeconfig and wiring to only trust PROXY data from raw TCP peers within a configured CIDR. - Implement
CidrRangeCIDR parsing/containment utility and unit tests. - Update
ProxyCustomizerto ignore PROXY-derived addresses for untrusted peers by wrapping requests withConnectionMetaData.Wrapper, plus add E2E coverage inProxyProtocolTest.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| rest-utils-ip-filtering-context.md | Adds detailed design/context documentation for the new peer-IP guard behavior. |
| core/src/main/java/io/confluent/rest/RestConfig.java | Defines the new proxy.protocol.accepted.ip.range config and documentation. |
| core/src/main/java/io/confluent/rest/ApplicationServer.java | Reads/parses the new config per listener and passes it into ProxyCustomizer. |
| core/src/main/java/io/confluent/rest/customizer/ProxyCustomizer.java | Adds accepted-range enforcement and RawPeerRequest wrapper to restore raw socket addresses. |
| core/src/main/java/io/confluent/rest/customizer/CidrRange.java | Adds CIDR parsing and containment checks. |
| core/src/test/java/io/confluent/rest/customizer/CidrRangeTest.java | Adds unit tests for CIDR parsing and containment edge cases. |
| core/src/test/java/io/confluent/rest/customizer/ProxyCustomizerTest.java | Adds unit tests for accepted-range behavior (in-range, out-of-range, and non-PROXY endpoints). |
| core/src/test/java/io/confluent/rest/ProxyProtocolTest.java | Adds E2E tests validating PROXY header is ignored/used depending on peer IP range. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
core/src/main/java/io/confluent/rest/customizer/ProxyCustomizer.java
Outdated
Show resolved
Hide resolved
…ata by peer IP During v3/v4 migration on GCP and Azure, both load balancer (v3, no PROXY protocol) and Envoy (v4, with PROXY protocol) connections coexist. Without this guard, an attacker can send a fake PROXY header through the v3 LB to spoof their IP and bypass IP filtering. This adds a new config `proxy.protocol.accepted.ip.range` (CIDR notation) that tells ProxyCustomizer to only trust PROXY protocol data from peers whose raw TCP IP falls within the range. Connections from outside the range get wrapped with a RawPeerRequest that overrides getRemoteAddr() back to the raw TCP peer IP using Jetty 12's ConnectionMetaData.Wrapper, effectively undoing the ProxyEndPoint's address override. Companion change to ce-kafka PR #28385. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- ProxyCustomizer: fail closed when peer address cannot be evaluated (non-InetSocketAddress or null InetAddress) instead of trusting PROXY data - CidrRange: use Guava InetAddresses.forString() instead of InetAddress.getByName() to reject hostnames and avoid DNS resolution during config parsing - CidrRange: trim address and prefix components before parsing Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
3009565 to
484d9a8
Compare
| @@ -0,0 +1,115 @@ | |||
| /* | |||
| * Copyright 2025 Confluent Inc. | |||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
During v3/v4 migration on GCP and Azure, both load balancer (v3, no PROXY protocol) and Envoy (v4, with PROXY protocol) connections coexist. Without this guard, an attacker can send a fake PROXY header through the v3 LB to spoof their IP and bypass IP filtering.
This adds a new config
proxy.protocol.accepted.ip.range(CIDR notation) that tells ProxyCustomizer to only trust PROXY protocol data from peers whose raw TCP IP falls within the range. Connections from outside the range get wrapped with a RawPeerRequest that overrides getRemoteAddr() back to the raw TCP peer IP using Jetty 12's ConnectionMetaData.Wrapper, effectively undoing the ProxyEndPoint's address override.Companion change to ce-kafka PR #28385.