VYPR
High severityNVD Advisory· Published Nov 7, 2024· Updated Nov 7, 2024

Apache ZooKeeper: Authentication bypass with IP-based authentication in Admin Server

CVE-2024-51504

Description

When using IPAuthenticationProvider in ZooKeeper Admin Server there is a possibility of Authentication Bypass by Spoofing -- this only impacts IP based authentication implemented in ZooKeeper Admin Server. Default configuration of client's IP address detection in IPAuthenticationProvider, which uses HTTP request headers, is weak and allows an attacker to bypass authentication via spoofing client's IP address in request headers. Default configuration honors X-Forwarded-For HTTP header to read client's IP address. X-Forwarded-For request header is mainly used by proxy servers to identify the client and can be easily spoofed by an attacker pretending that the request comes from a different IP address. Admin Server commands, such as snapshot and restore arbitrarily can be executed on successful exploitation which could potentially lead to information leakage or service availability issues. Users are recommended to upgrade to version 3.9.3, which fixes this issue.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Apache ZooKeeper 3.9.0-3.9.2 IPAuthenticationProvider defaults trust the X-Forwarded-For header, enabling unauthenticated attackers to bypass IP-based access control and execute admin commands via header spoofing.

CVE-2024-51504 is an authentication bypass vulnerability in the Apache ZooKeeper Admin Server. The IPAuthenticationProvider allows IP-based access lists to restrict admin endpoints. By default, it determines the client's IP address by reading the X-Forwarded-For HTTP request header before falling back to the connection source address [1][2]. This behavior is insecure because the header can be trivially spoofed by an attacker [1][3].

An attacker who can reach the ZooKeeper Admin Server (typically on a dedicated port) can set a forged X-Forwarded-For header to any trusted IP address. Successful authentication bypass allows execution of sensitive Admin Server commands, including snapshot and restore operations [1][3]. No prior authentication is needed, making the attack accessible to any network-adjacent or reachable adversary.

The impact includes potential information leakage (e.g., reading data snapshots) and denial of service via arbitrary restore actions [1]. The fix, introduced in ZooKeeper 3.9.3, adds a system property zookeeper.IPAuthenticationProvider.skipxforwardedfor; when set to true, the provider ignores the X-Forwarded-For header and uses the socket source address directly [2]. Users are advised to upgrade to 3.9.3 or later [1][3].

AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.apache.zookeeper:zookeeperMaven
>= 3.9.0, < 3.9.33.9.3

Affected products

20

Patches

1
2c2b74c1c11b

ZOOKEEPER-4851: Honor X-Forwarded-For optionally in IPAuthenticationProvider

https://github.com/apache/zookeeperAndor MolnárSep 3, 2024via ghsa
3 files changed · +101 0
  • zookeeper-docs/src/main/resources/markdown/zookeeperAdmin.md+10 0 modified
    @@ -1572,6 +1572,16 @@ 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.skipxforwardedfor* :
    +    (Java system property: **zookeeper.IPAuthenticationProvider.skipxforwardedfor**)
    +    **New in 3.9.3:**
    +    IPAuthenticationProvider needs the client IP address to authenticate the user.
    +    By default, it tries to read **X-Forwarded-For** HTTP header first and if it's not
    +    found, reads the **Host** header. Some proxy configuration requires this to
    +    properly identify the client IP, but we can disable it relying only on the **Host**
    +    header by setting this config option to **true**.
    +    Default value is **false**.
    +
     * *X509AuthenticationProvider.superUser* :
         (Java system property: **zookeeper.X509AuthenticationProvider.superUser**)
         The SSL-backed way to enable a ZooKeeper ensemble
    
  • zookeeper-server/src/main/java/org/apache/zookeeper/server/auth/IPAuthenticationProvider.java+6 0 modified
    @@ -30,6 +30,8 @@
     public class IPAuthenticationProvider implements AuthenticationProvider {
         public static final String X_FORWARDED_FOR_HEADER_NAME = "X-Forwarded-For";
     
    +    static final String SKIP_X_FORWARDED_FOR_KEY = "zookeeper.IPAuthenticationProvider.skipxforwardedfor";
    +
         public String getScheme() {
             return "ip";
         }
    @@ -150,6 +152,10 @@ public boolean isValid(String id) {
          * @return IP address
          */
         public static String getClientIPAddress(final HttpServletRequest request) {
    +        if (Boolean.getBoolean(SKIP_X_FORWARDED_FOR_KEY)) {
    +            return request.getRemoteAddr();
    +        }
    +
             // to handle the case that a HTTP(s) client connects via a proxy or load balancer
             final String xForwardedForHeader = request.getHeader(X_FORWARDED_FOR_HEADER_NAME);
             if (xForwardedForHeader == null) {
    
  • zookeeper-server/src/test/java/org/apache/zookeeper/server/auth/IPAuthenticationProviderTest.java+85 0 added
    @@ -0,0 +1,85 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one
    + * or more contributor license agreements.  See the NOTICE file
    + * distributed with this work for additional information
    + * regarding copyright ownership.  The ASF licenses this file
    + * to you under the Apache License, Version 2.0 (the
    + * "License"); you may not use this file except in compliance
    + * with the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +package org.apache.zookeeper.server.auth;
    +
    +import static org.apache.zookeeper.server.auth.IPAuthenticationProvider.SKIP_X_FORWARDED_FOR_KEY;
    +import static org.apache.zookeeper.server.auth.IPAuthenticationProvider.X_FORWARDED_FOR_HEADER_NAME;
    +import static org.junit.Assert.assertEquals;
    +import static org.mockito.Mockito.doReturn;
    +import static org.mockito.Mockito.mock;
    +import javax.servlet.http.HttpServletRequest;
    +import org.junit.After;
    +import org.junit.Before;
    +import org.junit.Test;
    +
    +public class IPAuthenticationProviderTest {
    +
    +  private HttpServletRequest request;
    +
    +  @Before
    +  public void setUp() throws Exception {
    +    System.clearProperty(SKIP_X_FORWARDED_FOR_KEY);
    +    request = mock(HttpServletRequest.class);
    +  }
    +
    +  @After
    +  public void tearDown() {
    +    System.clearProperty(SKIP_X_FORWARDED_FOR_KEY);
    +  }
    +
    +  @Test
    +  public void testGetClientIPAddressSkipXForwardedFor() {
    +    // Arrange
    +    System.setProperty(SKIP_X_FORWARDED_FOR_KEY, "true");
    +    doReturn("192.168.1.1").when(request).getRemoteAddr();
    +    doReturn("192.168.1.2,192.168.1.3,192.168.1.4").when(request).getHeader(X_FORWARDED_FOR_HEADER_NAME);
    +
    +    // Act
    +    String clientIp = IPAuthenticationProvider.getClientIPAddress(request);
    +
    +    // Assert
    +    assertEquals("192.168.1.1", clientIp);
    +  }
    +
    +  @Test
    +  public void testGetClientIPAddressWithXForwardedFor() {
    +    // Arrange
    +    System.setProperty(SKIP_X_FORWARDED_FOR_KEY, "false");
    +    doReturn("192.168.1.1").when(request).getRemoteAddr();
    +    doReturn("192.168.1.2,192.168.1.3,192.168.1.4").when(request).getHeader(X_FORWARDED_FOR_HEADER_NAME);
    +
    +    // Act
    +    String clientIp = IPAuthenticationProvider.getClientIPAddress(request);
    +
    +    // Assert
    +    assertEquals("192.168.1.2", clientIp);
    +  }
    +
    +  @Test
    +  public void testGetClientIPAddressMissingXForwardedFor() {
    +    // Arrange
    +    System.setProperty(SKIP_X_FORWARDED_FOR_KEY, "false");
    +    doReturn("192.168.1.1").when(request).getRemoteAddr();
    +
    +    // Act
    +    String clientIp = IPAuthenticationProvider.getClientIPAddress(request);
    +
    +    // Assert
    +    assertEquals("192.168.1.1", clientIp);
    +  }
    +}
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.