From 8fd91eb2fa8edec59c0e3cf982043909b0ba3bbc Mon Sep 17 00:00:00 2001 From: Andor Molnar Date: Mon, 27 Apr 2026 11:16:41 -0500 Subject: [PATCH 1/5] ZOOKEEPER-5042. Enhance docs of X-Forwarded-For --- .../main/resources/markdown/zookeeperAdmin.md | 40 +++++++++++++++---- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/zookeeper-docs/src/main/resources/markdown/zookeeperAdmin.md b/zookeeper-docs/src/main/resources/markdown/zookeeperAdmin.md index c87ce053e71..308865947b8 100644 --- a/zookeeper-docs/src/main/resources/markdown/zookeeperAdmin.md +++ b/zookeeper-docs/src/main/resources/markdown/zookeeperAdmin.md @@ -1579,16 +1579,42 @@ and [SASL authentication for ZooKeeper](https://cwiki.apache.org/confluence/disp - 1. Regenerate `superDigest` when migrating to new algorithm. - 2. `SetAcl` for a znode which already had a digest auth of old algorithm. + * *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** + +
**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**) From 47c16f45d1e9a27c45c9df4c6c86d25a100b925a Mon Sep 17 00:00:00 2001 From: Andor Molnar Date: Mon, 27 Apr 2026 11:18:50 -0500 Subject: [PATCH 2/5] ZOOKEEPER-5042. Styling --- .../src/main/resources/markdown/zookeeperAdmin.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/zookeeper-docs/src/main/resources/markdown/zookeeperAdmin.md b/zookeeper-docs/src/main/resources/markdown/zookeeperAdmin.md index 308865947b8..a52682c7e2f 100644 --- a/zookeeper-docs/src/main/resources/markdown/zookeeperAdmin.md +++ b/zookeeper-docs/src/main/resources/markdown/zookeeperAdmin.md @@ -1579,7 +1579,6 @@ and [SASL authentication for ZooKeeper](https://cwiki.apache.org/confluence/disp - 1. Regenerate `superDigest` when migrating to new algorithm. - 2. `SetAcl` for a znode which already had a digest auth of old algorithm. - * *IPAuthenticationProvider.usexforwardedfor* : (Java system property: **zookeeper.IPAuthenticationProvider.usexforwardedfor**) **New in 3.9.3:** @@ -1590,9 +1589,10 @@ and [SASL authentication for ZooKeeper](https://cwiki.apache.org/confluence/disp 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** -
**Security Warning** + **Security Warning** Enabling `usexforwardedfor` introduces significant security risks unless ZooKeeper is deployed strictly behind trusted, controlled proxy infrastructure: @@ -1605,7 +1605,7 @@ and [SASL authentication for ZooKeeper](https://cwiki.apache.org/confluence/disp - A malicious client may impersonate any IP address, potentially bypassing IP-based authentication and ZooKeeper ACL restrictions entirely. -
**Recommendation** + **Recommendation** Enable this setting **only** when: - ZooKeeper is accessible exclusively through trusted reverse proxies or load balancers @@ -1615,7 +1615,6 @@ and [SASL authentication for ZooKeeper](https://cwiki.apache.org/confluence/disp 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**) The SSL-backed way to enable a ZooKeeper ensemble From 760f19460bb2dc1423e0f4ac5e5294ca88901220 Mon Sep 17 00:00:00 2001 From: Andor Molnar Date: Mon, 27 Apr 2026 11:24:07 -0500 Subject: [PATCH 3/5] ZOOKEEPER-5042. Styling 2. --- .../src/main/resources/markdown/zookeeperAdmin.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/zookeeper-docs/src/main/resources/markdown/zookeeperAdmin.md b/zookeeper-docs/src/main/resources/markdown/zookeeperAdmin.md index a52682c7e2f..266c6ede6eb 100644 --- a/zookeeper-docs/src/main/resources/markdown/zookeeperAdmin.md +++ b/zookeeper-docs/src/main/resources/markdown/zookeeperAdmin.md @@ -1581,7 +1581,9 @@ 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` 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 @@ -1589,13 +1591,14 @@ and [SASL authentication for ZooKeeper](https://cwiki.apache.org/confluence/disp 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** - **Security Warning** +
**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 @@ -1608,6 +1611,7 @@ and [SASL authentication for ZooKeeper](https://cwiki.apache.org/confluence/disp **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 From b27306ef1335bbabceb910c8684e4d3df94f25e1 Mon Sep 17 00:00:00 2001 From: Andor Molnar Date: Mon, 27 Apr 2026 11:38:52 -0500 Subject: [PATCH 4/5] ZOOKEEPER-5042. Use rightmost IP address in the chain --- .../zookeeper/server/auth/IPAuthenticationProvider.java | 5 +++-- .../zookeeper/server/auth/IPAuthenticationProviderTest.java | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) 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 0b4ef9a703e..a3820469b6b 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 @@ -259,7 +259,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 1586cac39a3..fef027e0ff1 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 From e6312a283b8c2f1428b4b35324c455ae95846f28 Mon Sep 17 00:00:00 2001 From: Andor Molnar Date: Mon, 27 Apr 2026 12:17:38 -0500 Subject: [PATCH 5/5] ZOOKEEPER-5042. Unused import --- .../apache/zookeeper/server/auth/IPAuthenticationProvider.java | 1 - 1 file changed, 1 deletion(-) 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 a3820469b6b..8dd77305799 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;