This is an automated email from the ASF dual-hosted git repository.

anmolnar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/zookeeper.git


The following commit(s) were added to refs/heads/master by this push:
     new 410ceed4c ZOOKEEPER-5042: Enhance X-Forwarded-For setting in 
IPAuthenticationProvider
410ceed4c is described below

commit 410ceed4cc26a08df3f17a9b590a956e0e098b52
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
---
 .../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 1889faee3..7d9aa1738 100644
--- a/zookeeper-docs/src/main/resources/markdown/zookeeperAdmin.md
+++ b/zookeeper-docs/src/main/resources/markdown/zookeeperAdmin.md
@@ -1581,14 +1581,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

Reply via email to