Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 36 additions & 7 deletions zookeeper-docs/src/main/resources/markdown/zookeeperAdmin.md
Original file line number Diff line number Diff line change
Expand Up @@ -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**)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading