This is an automated email from the ASF dual-hosted git repository.
asf-gitbox-commits pushed a commit to branch branch-3.9
in repository https://gitbox.apache.org/repos/asf/zookeeper.git
The following commit(s) were added to refs/heads/branch-3.9 by this push:
new f2f783372 ZOOKEEPER-5042: Enhance X-Forwarded-For setting in
IPAuthenticationProvider
f2f783372 is described below
commit f2f78337265d6b69c5ff696c7578b35c135aa4ba
Author: Andor Molnár <[email protected]>
AuthorDate: Tue Jun 16 01:51:24 2026 +0200
ZOOKEEPER-5042: Enhance X-Forwarded-For setting in IPAuthenticationProvider
Author: anmolnar
Closes #2378 from anmolnar/ZOOKEEPER-5042
(cherry picked from commit 410ceed4cc26a08df3f17a9b590a956e0e098b52)
Signed-off-by: Andor Molnar <[email protected]>
---
.../src/main/resources/markdown/zookeeperAdmin.md | 43 ++++++++++++++++++----
.../server/auth/IPAuthenticationProvider.java | 6 +--
.../server/auth/IPAuthenticationProviderTest.java | 2 +-
3 files changed, 40 insertions(+), 11 deletions(-)
diff --git a/zookeeper-docs/src/main/resources/markdown/zookeeperAdmin.md
b/zookeeper-docs/src/main/resources/markdown/zookeeperAdmin.md
index b27d637b3..8b98d9058 100644
--- a/zookeeper-docs/src/main/resources/markdown/zookeeperAdmin.md
+++ b/zookeeper-docs/src/main/resources/markdown/zookeeperAdmin.md
@@ -1576,14 +1576,43 @@ and [SASL authentication for
ZooKeeper](https://cwiki.apache.org/confluence/disp
* *IPAuthenticationProvider.usexforwardedfor* :
(Java system property:
**zookeeper.IPAuthenticationProvider.usexforwardedfor**)
+
**New in 3.9.3:**
- IPAuthenticationProvider uses the client IP address to authenticate the
user. By
- default it reads the **Host** HTTP header to detect client IP address. In
some
- proxy configurations the proxy server adds the **X-Forwarded-For** header
to
- the request in order to provide the IP address of the original client
request.
- By enabling **usexforwardedfor** ZooKeeper setting, **X-Forwarded-For**
will be preferred
- over the standard **Host** header.
- Default value is **false**.
+
+ `IPAuthenticationProvider` authenticates clients based on their IP
address. By
+ default, ZooKeeper determines the client IP using the standard `Host` HTTP
header.
+ In certain reverse proxy or load balancer deployments, proxies may include
the
+ `X-Forwarded-For` header to indicate the originating client’s IP address.
+ When `usexforwardedfor` is enabled, ZooKeeper will prefer the
`X-Forwarded-For`
+ header over the `Host` header when determining the client IP address for
authentication
+ purposes.
+
+ Default value is **false**
+
+ <br/>**Security Warning**
+
+ Enabling `usexforwardedfor` introduces significant security risks unless
ZooKeeper
+ is deployed strictly behind trusted, controlled proxy infrastructure:
+
+ - ZooKeeper does **not** validate the `X-Forwarded-For` header against the
actual TCP
+ source IP address.
+ - ZooKeeper does **not** enforce a trusted proxy allowlist or verify that
the request
+ originated from an approved intermediary.
+ - Any client capable of connecting to ZooKeeper can forge an arbitrary
`X-Forwarded-For`
+ header value.
+ - A malicious client may impersonate any IP address, potentially bypassing
IP-based
+ authentication and ZooKeeper ACL restrictions entirely.
+
+ **Recommendation**
+
+ Enable this setting **only** when:
+
+ - ZooKeeper is accessible exclusively through trusted reverse proxies or
load balancers
+ - Direct client access is blocked at the network layer
+ - Proxy infrastructure sanitizes and overwrites incoming `X-Forwarded-For`
headers
+
+ For most deployments, leaving this property disabled is strongly
recommended to preserve
+ the integrity of IP-based access controls.
* *X509AuthenticationProvider.superUser* :
(Java system property: **zookeeper.X509AuthenticationProvider.superUser**)
diff --git
a/zookeeper-server/src/main/java/org/apache/zookeeper/server/auth/IPAuthenticationProvider.java
b/zookeeper-server/src/main/java/org/apache/zookeeper/server/auth/IPAuthenticationProvider.java
index 0b4ef9a70..8dd773057 100644
---
a/zookeeper-server/src/main/java/org/apache/zookeeper/server/auth/IPAuthenticationProvider.java
+++
b/zookeeper-server/src/main/java/org/apache/zookeeper/server/auth/IPAuthenticationProvider.java
@@ -21,7 +21,6 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import java.util.StringTokenizer;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import org.apache.zookeeper.KeeperException;
@@ -259,7 +258,8 @@ public static String getClientIPAddress(final
HttpServletRequest request) {
if (xForwardedForHeader == null) {
return request.getRemoteAddr();
}
- // the format of the field is: X-Forwarded-For: client, proxy1, proxy2
...
- return new StringTokenizer(xForwardedForHeader,
",").nextToken().trim();
+ // return the rightmost IP address in the X-Forwarded-For chain
+ String[] tokens = xForwardedForHeader.split(",");
+ return tokens[tokens.length - 1];
}
}
diff --git
a/zookeeper-server/src/test/java/org/apache/zookeeper/server/auth/IPAuthenticationProviderTest.java
b/zookeeper-server/src/test/java/org/apache/zookeeper/server/auth/IPAuthenticationProviderTest.java
index 1586cac39..fef027e0f 100644
---
a/zookeeper-server/src/test/java/org/apache/zookeeper/server/auth/IPAuthenticationProviderTest.java
+++
b/zookeeper-server/src/test/java/org/apache/zookeeper/server/auth/IPAuthenticationProviderTest.java
@@ -91,7 +91,7 @@ public void testGetClientIPAddressWithXForwardedFor() {
String clientIp = IPAuthenticationProvider.getClientIPAddress(request);
// Assert
- assertEquals("192.168.1.2", clientIp);
+ assertEquals("192.168.1.4", clientIp);
}
@Test