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
commit 44d5feb886ac96fd83b801b8122e792d9f758780 Author: Andor Molnar <[email protected]> AuthorDate: Tue Aug 25 16:18:14 2026 -0500 Missing ACL check on deleteContainer opcode --- .../apache/zookeeper/server/ZooKeeperServer.java | 10 ++++++++++ .../zookeeper/server/CreateContainerTest.java | 21 +++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/server/ZooKeeperServer.java b/zookeeper-server/src/main/java/org/apache/zookeeper/server/ZooKeeperServer.java index 080f4f863..9545730cb 100644 --- a/zookeeper-server/src/main/java/org/apache/zookeeper/server/ZooKeeperServer.java +++ b/zookeeper-server/src/main/java/org/apache/zookeeper/server/ZooKeeperServer.java @@ -1744,6 +1744,16 @@ public void processPacket(ServerCnxn cnxn, RequestHeader h, RequestRecord reques // Already sent response to user about failure and closed the session, lets return return; } else { + // Internal opcodes should not be submitted via client connections + if (h.getType() == OpCode.deleteContainer) { + LOG.warn("Received deleteContainer opcode from client session 0x{}, rejecting.", + Long.toHexString(cnxn.getSessionId())); + // close connection + cnxn.sendBuffer(ServerCnxnFactory.closeConn); + cnxn.disableRecv(); + return; + } + Request si = new Request(cnxn, cnxn.getSessionId(), h.getXid(), h.getType(), request, cnxn.getAuthInfo()); int length = request.limit(); if (isLargeRequest(length)) { diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/server/CreateContainerTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/server/CreateContainerTest.java index 589f61369..c6e39b482 100644 --- a/zookeeper-server/src/test/java/org/apache/zookeeper/server/CreateContainerTest.java +++ b/zookeeper-server/src/test/java/org/apache/zookeeper/server/CreateContainerTest.java @@ -42,9 +42,12 @@ import org.apache.zookeeper.DeleteContainerRequest; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.Op; +import org.apache.zookeeper.TestableZooKeeper; import org.apache.zookeeper.ZooDefs; import org.apache.zookeeper.ZooKeeper; import org.apache.zookeeper.data.Stat; +import org.apache.zookeeper.proto.ReplyHeader; +import org.apache.zookeeper.proto.RequestHeader; import org.apache.zookeeper.test.ClientBase; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -362,4 +365,22 @@ private void validateCreateStat(Stat stat, String name) { assertEquals(0, stat.getNumChildren()); } + @Test + @Timeout(value = 30) + public void testDeleteContainerShouldBeRejected() throws Exception { + zk.create("/some", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); + zk.create("/some/child", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); + + TestableZooKeeper zk = createClient(); + + RequestHeader h = new RequestHeader(); + h.setType(ZooDefs.OpCode.deleteContainer); + DeleteContainerRequest request = new DeleteContainerRequest("/some/child"); + ReplyHeader reply = zk.submitRequest(h, request, null, null); + assertEquals(KeeperException.Code.CONNECTIONLOSS.intValue(), reply.getErr(), + "deleteContainer opcode should be rejected from client connections"); + + zk.close(); + } + }
