CVE-2023-45859
Description
Missing permission checks in Hazelcast client operations allow authenticated users to access cluster data across multiple versions.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Missing permission checks in Hazelcast client operations allow authenticated users to access cluster data across multiple versions.
Root
Cause
The vulnerability stems from insufficient permission checks in certain client operations within Hazelcast. The official description states that "some client operations don't check permissions properly," allowing authenticated users to access data stored in the cluster [1]. This affects versions through 4.1.10, 4.2 through 4.2.8, 5.0 through 5.0.5, 5.1 through 5.1.7, 5.2 through 5.2.4, and 5.3 through 5.3.2 [4].
Exploitation
An authenticated user can exploit this flaw by sending crafted client operations that bypass permission checks. The attack does not require administrative privileges, as the improper checks occur in standard client message handling [2]. The adversary only needs valid credentials to connect to the cluster and send requests that should normally be restricted.
Impact
Successful exploitation allows an authenticated attacker to read, modify, or delete data that they are not authorized to access. This compromises the confidentiality and integrity of data stored in the Hazelcast cluster [4]. The vulnerability can lead to unauthorized data exposure or manipulation, depending on the cluster configuration.
Mitigation
Hazelcast has released patches in versions 5.2.5, 5.3.5, and 5.4.0-BETA-1 [4]. The fix extends permission checks in client messages and adds proper test coverage [2]. There is no known workaround; users are advised to upgrade to a patched version immediately.
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.
| Package | Affected versions | Patched versions |
|---|---|---|
com.hazelcast:hazelcastMaven | <= 4.1.10 | — |
com.hazelcast:hazelcastMaven | >= 4.2, <= 4.2.8 | — |
com.hazelcast:hazelcastMaven | >= 5.0, <= 5.0.5 | — |
com.hazelcast:hazelcastMaven | >= 5.1, <= 5.1.7 | — |
com.hazelcast:hazelcastMaven | >= 5.2.0, < 5.2.5 | 5.2.5 |
com.hazelcast:hazelcastMaven | >= 5.3.0, < 5.3.5 | 5.3.5 |
com.hazelcast:hazelcast-allMaven | <= 4.1.10 | — |
com.hazelcast:hazelcast-allMaven | >= 4.2, <= 4.2.8 | — |
Affected products
3- ghsa-coords2 versions
<= 4.1.10+ 1 more
- (no CPE)range: <= 4.1.10
- (no CPE)range: <= 4.1.10
Patches
38b1bd72a87adUpgrade version to 5.2.5
39 files changed · +39 −39
distribution/pom.xml+1 −1 modified@@ -21,7 +21,7 @@ <parent> <groupId>com.hazelcast</groupId> <artifactId>hazelcast-root</artifactId> - <version>5.2.5-SNAPSHOT</version> + <version>5.2.5</version> <relativePath>../pom.xml</relativePath> </parent>
extensions/avro/pom.xml+1 −1 modified@@ -30,7 +30,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-extensions</artifactId> - <version>5.2.5-SNAPSHOT</version> + <version>5.2.5</version> </parent> <build>
extensions/cdc-debezium/pom.xml+1 −1 modified@@ -29,7 +29,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-extensions</artifactId> - <version>5.2.5-SNAPSHOT</version> + <version>5.2.5</version> </parent> <properties>
extensions/cdc-mysql/pom.xml+1 −1 modified@@ -29,7 +29,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-extensions</artifactId> - <version>5.2.5-SNAPSHOT</version> + <version>5.2.5</version> </parent> <properties>
extensions/cdc-postgres/pom.xml+1 −1 modified@@ -29,7 +29,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-extensions</artifactId> - <version>5.2.5-SNAPSHOT</version> + <version>5.2.5</version> </parent> <properties>
extensions/csv/pom.xml+1 −1 modified@@ -30,7 +30,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-extensions</artifactId> - <version>5.2.5-SNAPSHOT</version> + <version>5.2.5</version> </parent> <build>
extensions/elasticsearch/elasticsearch-6/pom.xml+1 −1 modified@@ -30,7 +30,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-extensions</artifactId> - <version>5.2.5-SNAPSHOT</version> + <version>5.2.5</version> <relativePath>../../pom.xml</relativePath> </parent>
extensions/elasticsearch/elasticsearch-7/pom.xml+1 −1 modified@@ -30,7 +30,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-extensions</artifactId> - <version>5.2.5-SNAPSHOT</version> + <version>5.2.5</version> <relativePath>../../pom.xml</relativePath> </parent>
extensions/grpc/pom.xml+1 −1 modified@@ -24,7 +24,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-extensions</artifactId> - <version>5.2.5-SNAPSHOT</version> + <version>5.2.5</version> </parent> <build>
extensions/hadoop-dist/files-azure/pom.xml+1 −1 modified@@ -29,7 +29,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-hadoop-dist</artifactId> - <version>5.2.5-SNAPSHOT</version> + <version>5.2.5</version> </parent> <build>
extensions/hadoop-dist/files-gcs/pom.xml+1 −1 modified@@ -29,7 +29,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-hadoop-dist</artifactId> - <version>5.2.5-SNAPSHOT</version> + <version>5.2.5</version> </parent> <build>
extensions/hadoop-dist/files-s3/pom.xml+1 −1 modified@@ -29,7 +29,7 @@ <parent> <artifactId>hazelcast-jet-hadoop-dist</artifactId> <groupId>com.hazelcast.jet</groupId> - <version>5.2.5-SNAPSHOT</version> + <version>5.2.5</version> <relativePath>../pom.xml</relativePath> </parent>
extensions/hadoop-dist/hadoop-all/pom.xml+1 −1 modified@@ -29,7 +29,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-hadoop-dist</artifactId> - <version>5.2.5-SNAPSHOT</version> + <version>5.2.5</version> </parent> <build>
extensions/hadoop-dist/hadoop/pom.xml+1 −1 modified@@ -27,7 +27,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-hadoop-dist</artifactId> - <version>5.2.5-SNAPSHOT</version> + <version>5.2.5</version> </parent> <build>
extensions/hadoop-dist/pom.xml+1 −1 modified@@ -29,7 +29,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-extensions</artifactId> - <version>5.2.5-SNAPSHOT</version> + <version>5.2.5</version> </parent> <properties>
extensions/hadoop/pom.xml+1 −1 modified@@ -29,7 +29,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-extensions</artifactId> - <version>5.2.5-SNAPSHOT</version> + <version>5.2.5</version> </parent> <build>
extensions/hazelcast-3-connector/hazelcast-3-connector-common/pom.xml+1 −1 modified@@ -5,7 +5,7 @@ <parent> <artifactId>hazelcast-3-connector-root</artifactId> <groupId>com.hazelcast</groupId> - <version>5.2.5-SNAPSHOT</version> + <version>5.2.5</version> </parent> <artifactId>hazelcast-3-connector-common</artifactId>
extensions/hazelcast-3-connector/hazelcast-3-connector-impl/pom.xml+1 −1 modified@@ -5,7 +5,7 @@ <parent> <artifactId>hazelcast-3-connector-root</artifactId> <groupId>com.hazelcast</groupId> - <version>5.2.5-SNAPSHOT</version> + <version>5.2.5</version> </parent> <artifactId>hazelcast-3-connector-impl</artifactId>
extensions/hazelcast-3-connector/hazelcast-3-connector-interface/pom.xml+1 −1 modified@@ -5,7 +5,7 @@ <parent> <artifactId>hazelcast-3-connector-root</artifactId> <groupId>com.hazelcast</groupId> - <version>5.2.5-SNAPSHOT</version> + <version>5.2.5</version> </parent> <artifactId>hazelcast-3-connector-interface</artifactId>
extensions/hazelcast-3-connector/pom.xml+1 −1 modified@@ -6,7 +6,7 @@ <parent> <groupId>com.hazelcast</groupId> <artifactId>hazelcast-root</artifactId> - <version>5.2.5-SNAPSHOT</version> + <version>5.2.5</version> <relativePath>../../pom.xml</relativePath> </parent>
extensions/kafka/pom.xml+1 −1 modified@@ -29,7 +29,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-extensions</artifactId> - <version>5.2.5-SNAPSHOT</version> + <version>5.2.5</version> </parent> <build>
extensions/kinesis/pom.xml+1 −1 modified@@ -29,7 +29,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-extensions</artifactId> - <version>5.2.5-SNAPSHOT</version> + <version>5.2.5</version> </parent> <build>
extensions/mapstore/pom.xml+1 −1 modified@@ -32,7 +32,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-extensions</artifactId> - <version>5.2.5-SNAPSHOT</version> + <version>5.2.5</version> </parent> <build>
extensions/pom.xml+1 −1 modified@@ -30,7 +30,7 @@ <parent> <groupId>com.hazelcast</groupId> <artifactId>hazelcast-root</artifactId> - <version>5.2.5-SNAPSHOT</version> + <version>5.2.5</version> </parent> <modules>
extensions/protobuf/pom.xml+1 −1 modified@@ -30,7 +30,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-extensions</artifactId> - <version>5.2.5-SNAPSHOT</version> + <version>5.2.5</version> </parent> <build>
extensions/python/pom.xml+1 −1 modified@@ -24,7 +24,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-extensions</artifactId> - <version>5.2.5-SNAPSHOT</version> + <version>5.2.5</version> </parent> <build>
extensions/s3/pom.xml+1 −1 modified@@ -30,7 +30,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-extensions</artifactId> - <version>5.2.5-SNAPSHOT</version> + <version>5.2.5</version> </parent> <properties>
hazelcast-archunit-rules/pom.xml+1 −1 modified@@ -25,7 +25,7 @@ <parent> <groupId>com.hazelcast</groupId> <artifactId>hazelcast-root</artifactId> - <version>5.2.5-SNAPSHOT</version> + <version>5.2.5</version> <relativePath>../pom.xml</relativePath> </parent>
hazelcast-build-utils/pom.xml+1 −1 modified@@ -25,7 +25,7 @@ <parent> <groupId>com.hazelcast</groupId> <artifactId>hazelcast-root</artifactId> - <version>5.2.5-SNAPSHOT</version> + <version>5.2.5</version> <relativePath>../pom.xml</relativePath> </parent>
hazelcast-coverage-report/pom.xml+1 −1 modified@@ -20,7 +20,7 @@ <parent> <artifactId>hazelcast-root</artifactId> <groupId>com.hazelcast</groupId> - <version>5.2.5-SNAPSHOT</version> + <version>5.2.5</version> </parent> <modelVersion>4.0.0</modelVersion> <packaging>pom</packaging>
hazelcast-it/distribution-it/pom.xml+1 −1 modified@@ -6,7 +6,7 @@ <parent> <groupId>com.hazelcast</groupId> <artifactId>hazelcast-it</artifactId> - <version>5.2.5-SNAPSHOT</version> + <version>5.2.5</version> </parent> <artifactId>distribution-it</artifactId>
hazelcast-it/jdk17-tests/pom.xml+1 −1 modified@@ -6,7 +6,7 @@ <parent> <groupId>com.hazelcast</groupId> <artifactId>hazelcast-it</artifactId> - <version>5.2.5-SNAPSHOT</version> + <version>5.2.5</version> </parent> <artifactId>jdk17-tests</artifactId>
hazelcast-it/pom.xml+1 −1 modified@@ -22,7 +22,7 @@ <parent> <groupId>com.hazelcast</groupId> <artifactId>hazelcast-root</artifactId> - <version>5.2.5-SNAPSHOT</version> + <version>5.2.5</version> </parent> <artifactId>hazelcast-it</artifactId>
hazelcast/pom.xml+1 −1 modified@@ -26,7 +26,7 @@ <parent> <groupId>com.hazelcast</groupId> <artifactId>hazelcast-root</artifactId> - <version>5.2.5-SNAPSHOT</version> + <version>5.2.5</version> <relativePath>../pom.xml</relativePath> </parent>
hazelcast-spring/pom.xml+1 −1 modified@@ -25,7 +25,7 @@ <parent> <groupId>com.hazelcast</groupId> <artifactId>hazelcast-root</artifactId> - <version>5.2.5-SNAPSHOT</version> + <version>5.2.5</version> <relativePath>../pom.xml</relativePath> </parent>
hazelcast-spring-tests/pom.xml+1 −1 modified@@ -25,7 +25,7 @@ <parent> <groupId>com.hazelcast</groupId> <artifactId>hazelcast-root</artifactId> - <version>5.2.5-SNAPSHOT</version> + <version>5.2.5</version> <relativePath>../pom.xml</relativePath> </parent>
hazelcast-sql/pom.xml+1 −1 modified@@ -28,7 +28,7 @@ <parent> <groupId>com.hazelcast</groupId> <artifactId>hazelcast-root</artifactId> - <version>5.2.5-SNAPSHOT</version> + <version>5.2.5</version> <relativePath>../pom.xml</relativePath> </parent>
modulepath-tests/pom.xml+1 −1 modified@@ -27,7 +27,7 @@ <parent> <groupId>com.hazelcast</groupId> <artifactId>hazelcast-root</artifactId> - <version>5.2.5-SNAPSHOT</version> + <version>5.2.5</version> <relativePath>../pom.xml</relativePath> </parent>
pom.xml+1 −1 modified@@ -23,7 +23,7 @@ <groupId>com.hazelcast</groupId> <artifactId>hazelcast-root</artifactId> <packaging>pom</packaging> - <version>5.2.5-SNAPSHOT</version> + <version>5.2.5</version> <name>Hazelcast Root</name> <description>Hazelcast In-Memory DataGrid</description> <url>http://www.hazelcast.com/</url>
7e760b071f27Upgrade version to 5.3.5
42 files changed · +43 −43
distribution/pom.xml+1 −1 modified@@ -21,7 +21,7 @@ <parent> <groupId>com.hazelcast</groupId> <artifactId>hazelcast-root</artifactId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> <relativePath>../pom.xml</relativePath> </parent>
extensions/avro/pom.xml+1 −1 modified@@ -30,7 +30,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-extensions</artifactId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> </parent> <build>
extensions/cdc-debezium/pom.xml+1 −1 modified@@ -29,7 +29,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-extensions</artifactId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> </parent> <properties>
extensions/cdc-mysql/pom.xml+1 −1 modified@@ -29,7 +29,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-extensions</artifactId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> </parent> <properties>
extensions/cdc-postgres/pom.xml+1 −1 modified@@ -29,7 +29,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-extensions</artifactId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> </parent> <properties>
extensions/csv/pom.xml+1 −1 modified@@ -30,7 +30,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-extensions</artifactId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> </parent> <build>
extensions/elasticsearch/elasticsearch-6/pom.xml+1 −1 modified@@ -30,7 +30,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-extensions</artifactId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> <relativePath>../../pom.xml</relativePath> </parent>
extensions/elasticsearch/elasticsearch-7/pom.xml+1 −1 modified@@ -30,7 +30,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-extensions</artifactId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> <relativePath>../../pom.xml</relativePath> </parent>
extensions/grpc/pom.xml+1 −1 modified@@ -24,7 +24,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-extensions</artifactId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> </parent> <build>
extensions/hadoop-dist/files-azure/pom.xml+1 −1 modified@@ -29,7 +29,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-hadoop-dist</artifactId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> </parent> <build>
extensions/hadoop-dist/files-gcs/pom.xml+1 −1 modified@@ -29,7 +29,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-hadoop-dist</artifactId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> </parent> <build>
extensions/hadoop-dist/files-s3/pom.xml+1 −1 modified@@ -29,7 +29,7 @@ <parent> <artifactId>hazelcast-jet-hadoop-dist</artifactId> <groupId>com.hazelcast.jet</groupId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> <relativePath>../pom.xml</relativePath> </parent>
extensions/hadoop-dist/hadoop-all/pom.xml+1 −1 modified@@ -29,7 +29,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-hadoop-dist</artifactId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> </parent> <build>
extensions/hadoop-dist/hadoop/pom.xml+1 −1 modified@@ -27,7 +27,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-hadoop-dist</artifactId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> </parent> <build>
extensions/hadoop-dist/pom.xml+1 −1 modified@@ -29,7 +29,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-extensions</artifactId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> </parent> <properties>
extensions/hadoop/pom.xml+1 −1 modified@@ -29,7 +29,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-extensions</artifactId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> </parent> <build>
extensions/hazelcast-3-connector/hazelcast-3-connector-common/pom.xml+1 −1 modified@@ -5,7 +5,7 @@ <parent> <artifactId>hazelcast-3-connector-root</artifactId> <groupId>com.hazelcast</groupId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> </parent> <artifactId>hazelcast-3-connector-common</artifactId>
extensions/hazelcast-3-connector/hazelcast-3-connector-impl/pom.xml+1 −1 modified@@ -5,7 +5,7 @@ <parent> <artifactId>hazelcast-3-connector-root</artifactId> <groupId>com.hazelcast</groupId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> </parent> <artifactId>hazelcast-3-connector-impl</artifactId>
extensions/hazelcast-3-connector/hazelcast-3-connector-interface/pom.xml+1 −1 modified@@ -5,7 +5,7 @@ <parent> <artifactId>hazelcast-3-connector-root</artifactId> <groupId>com.hazelcast</groupId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> </parent> <artifactId>hazelcast-3-connector-interface</artifactId>
extensions/hazelcast-3-connector/pom.xml+1 −1 modified@@ -6,7 +6,7 @@ <parent> <groupId>com.hazelcast</groupId> <artifactId>hazelcast-root</artifactId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> <relativePath>../../pom.xml</relativePath> </parent>
extensions/kafka-connect/pom.xml+1 −1 modified@@ -29,7 +29,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-extensions</artifactId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> </parent> <build>
extensions/kafka/pom.xml+1 −1 modified@@ -29,7 +29,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-extensions</artifactId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> </parent> <build>
extensions/kinesis/pom.xml+1 −1 modified@@ -29,7 +29,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-extensions</artifactId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> </parent> <build>
extensions/mapstore/pom.xml+1 −1 modified@@ -32,7 +32,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-extensions</artifactId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> </parent> <build>
extensions/mongodb/pom.xml+1 −1 modified@@ -31,7 +31,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-extensions</artifactId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> </parent> <build>
extensions/pom.xml+1 −1 modified@@ -30,7 +30,7 @@ <parent> <groupId>com.hazelcast</groupId> <artifactId>hazelcast-root</artifactId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> </parent> <modules>
extensions/protobuf/pom.xml+1 −1 modified@@ -30,7 +30,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-extensions</artifactId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> </parent> <build>
extensions/python/pom.xml+1 −1 modified@@ -24,7 +24,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-extensions</artifactId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> </parent> <build>
extensions/s3/pom.xml+1 −1 modified@@ -30,7 +30,7 @@ <parent> <groupId>com.hazelcast.jet</groupId> <artifactId>hazelcast-jet-extensions</artifactId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> </parent> <properties>
hazelcast-archunit-rules/pom.xml+1 −1 modified@@ -25,7 +25,7 @@ <parent> <groupId>com.hazelcast</groupId> <artifactId>hazelcast-root</artifactId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> <relativePath>../pom.xml</relativePath> </parent>
hazelcast-build-utils/pom.xml+1 −1 modified@@ -25,7 +25,7 @@ <parent> <groupId>com.hazelcast</groupId> <artifactId>hazelcast-root</artifactId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> <relativePath>../pom.xml</relativePath> </parent>
hazelcast-coverage-report/pom.xml+1 −1 modified@@ -20,7 +20,7 @@ <parent> <artifactId>hazelcast-root</artifactId> <groupId>com.hazelcast</groupId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> </parent> <modelVersion>4.0.0</modelVersion> <packaging>pom</packaging>
hazelcast-it/distribution-it/pom.xml+1 −1 modified@@ -6,7 +6,7 @@ <parent> <groupId>com.hazelcast</groupId> <artifactId>hazelcast-it</artifactId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> </parent> <artifactId>distribution-it</artifactId>
hazelcast-it/jdk17-tests/pom.xml+1 −1 modified@@ -6,7 +6,7 @@ <parent> <groupId>com.hazelcast</groupId> <artifactId>hazelcast-it</artifactId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> </parent> <artifactId>jdk17-tests</artifactId>
hazelcast-it/pom.xml+1 −1 modified@@ -22,7 +22,7 @@ <parent> <groupId>com.hazelcast</groupId> <artifactId>hazelcast-root</artifactId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> </parent> <artifactId>hazelcast-it</artifactId>
hazelcast/pom.xml+2 −2 modified@@ -26,7 +26,7 @@ <parent> <groupId>com.hazelcast</groupId> <artifactId>hazelcast-root</artifactId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> <relativePath>../pom.xml</relativePath> </parent> @@ -468,7 +468,7 @@ <dependency> <groupId>com.hazelcast</groupId> <artifactId>hazelcast-tpc-engine</artifactId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> </dependency> <dependency>
hazelcast-spring/pom.xml+1 −1 modified@@ -25,7 +25,7 @@ <parent> <groupId>com.hazelcast</groupId> <artifactId>hazelcast-root</artifactId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> <relativePath>../pom.xml</relativePath> </parent>
hazelcast-spring-tests/pom.xml+1 −1 modified@@ -25,7 +25,7 @@ <parent> <groupId>com.hazelcast</groupId> <artifactId>hazelcast-root</artifactId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> <relativePath>../pom.xml</relativePath> </parent>
hazelcast-sql/pom.xml+1 −1 modified@@ -28,7 +28,7 @@ <parent> <groupId>com.hazelcast</groupId> <artifactId>hazelcast-root</artifactId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> <relativePath>../pom.xml</relativePath> </parent>
hazelcast-tpc-engine/pom.xml+1 −1 modified@@ -28,7 +28,7 @@ <parent> <groupId>com.hazelcast</groupId> <artifactId>hazelcast-root</artifactId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> <relativePath>../pom.xml</relativePath> </parent>
modulepath-tests/pom.xml+1 −1 modified@@ -27,7 +27,7 @@ <parent> <groupId>com.hazelcast</groupId> <artifactId>hazelcast-root</artifactId> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> <relativePath>../pom.xml</relativePath> </parent>
pom.xml+1 −1 modified@@ -23,7 +23,7 @@ <groupId>com.hazelcast</groupId> <artifactId>hazelcast-root</artifactId> <packaging>pom</packaging> - <version>5.3.5-SNAPSHOT</version> + <version>5.3.5</version> <name>Hazelcast Root</name> <description>Hazelcast In-Memory DataGrid</description> <url>http://www.hazelcast.com/</url>
8150451b5148Extend permission checks in MessageTasks and add a test coverage [HZ-2090] (#25509)
23 files changed · +277 −22
.github/CODEOWNERS+1 −0 modified@@ -6,3 +6,4 @@ **/client/** @hazelcast/apis **/hazelcast-client** @hazelcast/apis +**/MessageTaskSecurityTest* @hazelcast/security-working-group
hazelcast/src/main/java/com/hazelcast/client/impl/protocol/task/cache/CacheAddNearCacheInvalidationListenerTask.java+3 −1 modified@@ -26,6 +26,8 @@ import com.hazelcast.internal.nearcache.impl.invalidation.Invalidation; import com.hazelcast.internal.nio.Connection; import com.hazelcast.internal.serialization.Data; +import com.hazelcast.security.permission.ActionConstants; +import com.hazelcast.security.permission.CachePermission; import java.security.Permission; import java.util.List; @@ -118,7 +120,7 @@ public String getServiceName() { @Override public Permission getRequiredPermission() { - return null; + return new CachePermission(parameters.name, ActionConstants.ACTION_LISTEN); } }
hazelcast/src/main/java/com/hazelcast/client/impl/protocol/task/cache/CacheAddPartitionLostListenerMessageTask.java+3 −1 modified@@ -26,6 +26,8 @@ import com.hazelcast.client.impl.protocol.task.AbstractAddListenerMessageTask; import com.hazelcast.instance.impl.Node; import com.hazelcast.internal.nio.Connection; +import com.hazelcast.security.permission.ActionConstants; +import com.hazelcast.security.permission.CachePermission; import com.hazelcast.spi.impl.eventservice.EventFilter; import com.hazelcast.spi.impl.eventservice.EventRegistration; import com.hazelcast.spi.impl.eventservice.EventService; @@ -96,7 +98,7 @@ public Object[] getParameters() { @Override public Permission getRequiredPermission() { - return null; + return new CachePermission(parameters.name, ActionConstants.ACTION_LISTEN); } @Override
hazelcast/src/main/java/com/hazelcast/client/impl/protocol/task/cache/CacheCreateConfigMessageTask.java+2 −1 modified@@ -26,6 +26,7 @@ import com.hazelcast.config.CacheConfig; import com.hazelcast.instance.impl.Node; import com.hazelcast.internal.nio.Connection; +import com.hazelcast.security.permission.ConfigPermission; import com.hazelcast.spi.impl.InternalCompletableFuture; import com.hazelcast.spi.merge.SplitBrainMergePolicyProvider; @@ -80,7 +81,7 @@ public String getServiceName() { @Override public Permission getRequiredPermission() { - return null; + return new ConfigPermission(); } @Override
hazelcast/src/main/java/com/hazelcast/client/impl/protocol/task/cache/CacheDestroyMessageTask.java+4 −2 modified@@ -23,6 +23,8 @@ import com.hazelcast.client.impl.protocol.task.AbstractInvocationMessageTask; import com.hazelcast.instance.impl.Node; import com.hazelcast.internal.nio.Connection; +import com.hazelcast.security.permission.ActionConstants; +import com.hazelcast.security.permission.CachePermission; import com.hazelcast.spi.impl.operationservice.InvocationBuilder; import com.hazelcast.spi.impl.operationservice.Operation; import com.hazelcast.spi.impl.operationservice.impl.OperationServiceImpl; @@ -66,12 +68,12 @@ public String getServiceName() { @Override public Permission getRequiredPermission() { - return null; + return new CachePermission(parameters, ActionConstants.ACTION_DESTROY); } @Override public String getDistributedObjectName() { - return null; + return parameters; } @Override
hazelcast/src/main/java/com/hazelcast/client/impl/protocol/task/cache/CacheGetConfigMessageTask.java+3 −1 modified@@ -24,6 +24,8 @@ import com.hazelcast.config.CacheConfig; import com.hazelcast.instance.impl.Node; import com.hazelcast.internal.nio.Connection; +import com.hazelcast.security.permission.ActionConstants; +import com.hazelcast.security.permission.CachePermission; import com.hazelcast.spi.impl.operationservice.Operation; import java.security.Permission; @@ -70,7 +72,7 @@ public Object[] getParameters() { @Override public Permission getRequiredPermission() { - return null; + return new CachePermission(parameters.name, ActionConstants.ACTION_READ); } @Override
hazelcast/src/main/java/com/hazelcast/client/impl/protocol/task/cache/CacheIterateMessageTask.java+8 −0 modified@@ -24,8 +24,11 @@ import com.hazelcast.instance.impl.Node; import com.hazelcast.internal.iteration.IterationPointer; import com.hazelcast.internal.nio.Connection; +import com.hazelcast.security.permission.ActionConstants; +import com.hazelcast.security.permission.CachePermission; import com.hazelcast.spi.impl.operationservice.Operation; +import java.security.Permission; import java.util.Collections; import static com.hazelcast.internal.iteration.IterationPointer.decodePointers; @@ -79,4 +82,9 @@ public Object[] getParameters() { public String getMethodName() { return "iterator"; } + + @Override + public Permission getRequiredPermission() { + return new CachePermission(parameters.name, ActionConstants.ACTION_READ); + } }
hazelcast/src/main/java/com/hazelcast/client/impl/protocol/task/cache/CacheListenerRegistrationMessageTask.java+3 −1 modified@@ -23,6 +23,8 @@ import com.hazelcast.client.impl.protocol.task.AbstractTargetMessageTask; import com.hazelcast.instance.impl.Node; import com.hazelcast.internal.nio.Connection; +import com.hazelcast.security.permission.ActionConstants; +import com.hazelcast.security.permission.CachePermission; import com.hazelcast.spi.impl.operationservice.Operation; import javax.cache.configuration.CacheEntryListenerConfiguration; @@ -69,7 +71,7 @@ public String getServiceName() { @Override public Permission getRequiredPermission() { - return null; + return new CachePermission(parameters.name, ActionConstants.ACTION_LISTEN); } @Override
hazelcast/src/main/java/com/hazelcast/client/impl/protocol/task/cache/CacheLoadAllMessageTask.java+3 −1 modified@@ -25,6 +25,8 @@ import com.hazelcast.instance.impl.Node; import com.hazelcast.internal.nio.Connection; import com.hazelcast.internal.serialization.Data; +import com.hazelcast.security.permission.ActionConstants; +import com.hazelcast.security.permission.CachePermission; import com.hazelcast.spi.impl.operationservice.OperationFactory; import javax.cache.CacheException; @@ -84,7 +86,7 @@ public String getServiceName() { @Override public Permission getRequiredPermission() { - return null; + return new CachePermission(parameters.name, ActionConstants.ACTION_READ); } @Override
hazelcast/src/main/java/com/hazelcast/client/impl/protocol/task/cache/CacheManagementConfigMessageTask.java+2 −1 modified@@ -23,6 +23,7 @@ import com.hazelcast.client.impl.protocol.task.AbstractTargetMessageTask; import com.hazelcast.instance.impl.Node; import com.hazelcast.internal.nio.Connection; +import com.hazelcast.security.permission.ConfigPermission; import com.hazelcast.spi.impl.operationservice.Operation; import java.security.Permission; @@ -67,7 +68,7 @@ public String getServiceName() { @Override public Permission getRequiredPermission() { - return null; + return new ConfigPermission(); } @Override
hazelcast/src/main/java/com/hazelcast/client/impl/protocol/task/cache/CacheRemoveInvalidationListenerMessageTask.java+3 −1 modified@@ -22,6 +22,8 @@ import com.hazelcast.client.impl.protocol.task.AbstractRemoveListenerMessageTask; import com.hazelcast.instance.impl.Node; import com.hazelcast.internal.nio.Connection; +import com.hazelcast.security.permission.ActionConstants; +import com.hazelcast.security.permission.CachePermission; import java.security.Permission; import java.util.UUID; @@ -72,7 +74,7 @@ public String getDistributedObjectName() { @Override public Permission getRequiredPermission() { - return null; + return new CachePermission(parameters.name, ActionConstants.ACTION_LISTEN); } @Override
hazelcast/src/main/java/com/hazelcast/client/impl/protocol/task/cache/CacheRemovePartitionLostListenerMessageTask.java+3 −1 modified@@ -23,6 +23,8 @@ import com.hazelcast.client.impl.protocol.task.AbstractRemoveListenerMessageTask; import com.hazelcast.instance.impl.Node; import com.hazelcast.internal.nio.Connection; +import com.hazelcast.security.permission.ActionConstants; +import com.hazelcast.security.permission.CachePermission; import java.security.Permission; import java.util.UUID; @@ -70,7 +72,7 @@ public String getDistributedObjectName() { @Override public Permission getRequiredPermission() { - return null; + return new CachePermission(parameters.name, ActionConstants.ACTION_LISTEN); } @Override
hazelcast/src/main/java/com/hazelcast/client/impl/protocol/task/CreateProxiesMessageTask.java+25 −0 modified@@ -22,7 +22,10 @@ import com.hazelcast.core.MemberLeftException; import com.hazelcast.instance.impl.Node; import com.hazelcast.internal.nio.Connection; +import com.hazelcast.security.SecurityContext; +import com.hazelcast.security.permission.ActionConstants; import com.hazelcast.spi.impl.operationservice.Operation; +import com.hazelcast.spi.impl.proxyservice.ProxyService; import com.hazelcast.spi.impl.proxyservice.impl.ProxyInfo; import com.hazelcast.spi.impl.proxyservice.impl.operations.PostJoinProxyOperation; @@ -79,11 +82,33 @@ protected ClientMessage encodeResponse(Object response) { return ClientCreateProxiesCodec.encodeResponse(); } + /** + *@see #beforeProcess() + */ @Override public Permission getRequiredPermission() { return null; } + @Override + protected void beforeProcess() { + // replacement for getRequiredPermission-based checks, we have to check multiple permission + SecurityContext securityContext = clientEngine.getSecurityContext(); + if (securityContext != null) { + ProxyService proxyService = clientEngine.getProxyService(); + for (Map.Entry<String, String> proxy : parameters) { + String objectName = proxy.getKey(); + String serviceName = proxy.getValue(); + if (proxyService.existsDistributedObject(serviceName, objectName)) { + continue; + } + Permission permission = ActionConstants.getPermission(objectName, serviceName, ActionConstants.ACTION_CREATE); + securityContext.checkPermission(endpoint.getSubject(), permission); + } + } + super.beforeProcess(); + } + @Override public String getServiceName() { return null;
hazelcast/src/main/java/com/hazelcast/client/impl/protocol/task/map/MapDestroyCacheMessageTask.java+3 −1 modified@@ -23,6 +23,8 @@ import com.hazelcast.instance.impl.Node; import com.hazelcast.internal.nio.Connection; import com.hazelcast.map.impl.querycache.subscriber.operation.DestroyQueryCacheOperation; +import com.hazelcast.security.permission.ActionConstants; +import com.hazelcast.security.permission.MapPermission; import com.hazelcast.spi.impl.operationservice.Operation; import java.security.Permission; @@ -76,7 +78,7 @@ public String getServiceName() { @Override public Permission getRequiredPermission() { - return null; + return new MapPermission(parameters.mapName, ActionConstants.ACTION_DESTROY); } @Override
hazelcast/src/main/java/com/hazelcast/client/impl/protocol/task/map/MapFetchEntriesMessageTask.java+3 −1 modified@@ -24,6 +24,8 @@ import com.hazelcast.map.impl.MapService; import com.hazelcast.map.impl.iterator.MapEntriesWithCursor; import com.hazelcast.map.impl.operation.MapOperationProvider; +import com.hazelcast.security.permission.ActionConstants; +import com.hazelcast.security.permission.MapPermission; import com.hazelcast.spi.impl.operationservice.Operation; import java.security.Permission; @@ -67,7 +69,7 @@ public String getServiceName() { @Override public Permission getRequiredPermission() { - return null; + return new MapPermission(parameters.name, ActionConstants.ACTION_READ); } @Override
hazelcast/src/main/java/com/hazelcast/client/impl/protocol/task/map/MapFetchKeysMessageTask.java+3 −1 modified@@ -24,6 +24,8 @@ import com.hazelcast.map.impl.MapService; import com.hazelcast.map.impl.iterator.MapKeysWithCursor; import com.hazelcast.map.impl.operation.MapOperationProvider; +import com.hazelcast.security.permission.ActionConstants; +import com.hazelcast.security.permission.MapPermission; import com.hazelcast.spi.impl.operationservice.Operation; import java.security.Permission; @@ -67,7 +69,7 @@ public String getServiceName() { @Override public Permission getRequiredPermission() { - return null; + return new MapPermission(parameters.name, ActionConstants.ACTION_READ); } @Override
hazelcast/src/main/java/com/hazelcast/client/impl/protocol/task/map/MapPublisherCreateMessageTask.java+3 −1 modified@@ -33,6 +33,8 @@ import com.hazelcast.internal.nio.Connection; import com.hazelcast.internal.serialization.Data; import com.hazelcast.query.Predicate; +import com.hazelcast.security.permission.ActionConstants; +import com.hazelcast.security.permission.MapPermission; import com.hazelcast.spi.impl.operationservice.InvocationBuilder; import com.hazelcast.spi.impl.operationservice.impl.OperationServiceImpl; import com.hazelcast.internal.util.ExceptionUtil; @@ -136,7 +138,7 @@ public String getServiceName() { @Override public Permission getRequiredPermission() { - return null; + return new MapPermission(parameters.mapName, ActionConstants.ACTION_LISTEN); } @Override
hazelcast/src/main/java/com/hazelcast/client/impl/protocol/task/map/MapPublisherCreateWithValueMessageTask.java+5 −3 modified@@ -33,6 +33,8 @@ import com.hazelcast.internal.nio.Connection; import com.hazelcast.internal.serialization.Data; import com.hazelcast.query.Predicate; +import com.hazelcast.security.permission.ActionConstants; +import com.hazelcast.security.permission.MapPermission; import com.hazelcast.spi.impl.operationservice.InvocationBuilder; import com.hazelcast.spi.impl.operationservice.impl.OperationServiceImpl; import com.hazelcast.internal.util.ExceptionUtil; @@ -98,8 +100,8 @@ private static Set<Map.Entry<Data, Data>> fetchMapSnapshotFrom(List<Future> futu Object result; try { result = future.get(); - } catch (Throwable t) { - throw ExceptionUtil.rethrow(t); + } catch (Exception e) { + throw ExceptionUtil.rethrow(e); } if (result == null) { continue; @@ -139,7 +141,7 @@ public String getServiceName() { @Override public Permission getRequiredPermission() { - return null; + return new MapPermission(parameters.mapName, ActionConstants.ACTION_LISTEN); } @Override
hazelcast/src/main/java/com/hazelcast/client/impl/protocol/task/map/MapRemovePartitionLostListenerMessageTask.java+3 −1 modified@@ -22,6 +22,8 @@ import com.hazelcast.instance.impl.Node; import com.hazelcast.internal.nio.Connection; import com.hazelcast.map.impl.MapService; +import com.hazelcast.security.permission.ActionConstants; +import com.hazelcast.security.permission.MapPermission; import java.security.Permission; import java.util.UUID; @@ -68,7 +70,7 @@ public String getDistributedObjectName() { @Override public Permission getRequiredPermission() { - return null; + return new MapPermission(parameters.name, ActionConstants.ACTION_LISTEN); } @Override
hazelcast/src/main/java/com/hazelcast/client/impl/protocol/task/map/MapSetReadCursorMessageTask.java+3 −1 modified@@ -22,6 +22,8 @@ import com.hazelcast.instance.impl.Node; import com.hazelcast.map.impl.MapService; import com.hazelcast.map.impl.querycache.subscriber.operation.SetReadCursorOperation; +import com.hazelcast.security.permission.ActionConstants; +import com.hazelcast.security.permission.MapPermission; import com.hazelcast.internal.nio.Connection; import com.hazelcast.spi.impl.operationservice.Operation; @@ -55,7 +57,7 @@ public String getServiceName() { @Override public Permission getRequiredPermission() { - return null; + return new MapPermission(parameters.mapName, ActionConstants.ACTION_READ); } @Override
hazelcast/src/main/java/com/hazelcast/cp/internal/datastructures/semaphore/client/GetSemaphoreTypeMessageTask.java+3 −1 modified@@ -23,6 +23,8 @@ import com.hazelcast.cp.internal.datastructures.semaphore.SemaphoreService; import com.hazelcast.instance.impl.Node; import com.hazelcast.internal.nio.Connection; +import com.hazelcast.security.permission.ActionConstants; +import com.hazelcast.security.permission.SemaphorePermission; import java.security.Permission; @@ -59,7 +61,7 @@ public String getServiceName() { @Override public Permission getRequiredPermission() { - return null; + return new SemaphorePermission(parameters, ActionConstants.ACTION_READ); } @Override
hazelcast/src/main/java/com/hazelcast/sql/impl/client/SqlMappingDdlTask.java+3 −1 modified@@ -20,6 +20,8 @@ import com.hazelcast.client.impl.protocol.codec.SqlMappingDdlCodec; import com.hazelcast.instance.impl.Node; import com.hazelcast.internal.nio.Connection; +import com.hazelcast.security.permission.ActionConstants; +import com.hazelcast.security.permission.MapPermission; import com.hazelcast.sql.impl.InternalSqlService; import java.security.Permission; @@ -71,6 +73,6 @@ public Object[] getParameters() { @Override public Permission getRequiredPermission() { - return null; + return new MapPermission(parameters, ActionConstants.ACTION_READ); } }
hazelcast/src/test/java/com/hazelcast/client/protocol/MessageTaskSecurityTest.java+185 −0 added@@ -0,0 +1,185 @@ +/* + * Copyright (c) 2008-2023, Hazelcast, Inc. All Rights Reserved. + * + * Licensed 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 com.hazelcast.client.protocol; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + +import java.lang.reflect.Modifier; +import java.util.Arrays; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import org.assertj.core.api.Assertions; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.runner.RunWith; +import org.reflections.Reflections; + +import com.hazelcast.client.impl.protocol.task.AbstractMessageTask; +import com.hazelcast.client.impl.protocol.task.AddBackupListenerMessageTask; +import com.hazelcast.client.impl.protocol.task.AddClusterViewListenerMessageTask; +import com.hazelcast.client.impl.protocol.task.AddDistributedObjectListenerMessageTask; +import com.hazelcast.client.impl.protocol.task.AddMigrationListenerMessageTask; +import com.hazelcast.client.impl.protocol.task.AddPartitionLostListenerMessageTask; +import com.hazelcast.client.impl.protocol.task.AuthenticationCustomCredentialsMessageTask; +import com.hazelcast.client.impl.protocol.task.AuthenticationMessageTask; +import com.hazelcast.client.impl.protocol.task.ClientStatisticsMessageTask; +import com.hazelcast.client.impl.protocol.task.CreateProxiesMessageTask; +import com.hazelcast.client.impl.protocol.task.ExperimentalAuthenticationCustomCredentialsMessageTask; +import com.hazelcast.client.impl.protocol.task.ExperimentalAuthenticationMessageTask; +import com.hazelcast.client.impl.protocol.task.ExperimentalTpcAuthenticationMessageTask; +import com.hazelcast.client.impl.protocol.task.GetDistributedObjectsMessageTask; +import com.hazelcast.client.impl.protocol.task.MessageTask; +import com.hazelcast.client.impl.protocol.task.NoSuchMessageTask; +import com.hazelcast.client.impl.protocol.task.PingMessageTask; +import com.hazelcast.client.impl.protocol.task.RemoveDistributedObjectListenerMessageTask; +import com.hazelcast.client.impl.protocol.task.RemoveMigrationListenerMessageTask; +import com.hazelcast.client.impl.protocol.task.RemovePartitionLostListenerMessageTask; +import com.hazelcast.client.impl.protocol.task.TriggerPartitionAssignmentMessageTask; +import com.hazelcast.client.impl.protocol.task.cache.CacheFetchNearCacheInvalidationMetadataTask; +import com.hazelcast.client.impl.protocol.task.map.MapAddListenerMessageTask; +import com.hazelcast.client.impl.protocol.task.map.MapFetchNearCacheInvalidationMetadataTask; +import com.hazelcast.client.impl.protocol.task.map.MapMadePublishableMessageTask; +import com.hazelcast.client.impl.protocol.task.schema.FetchSchemaMessageTask; +import com.hazelcast.client.impl.protocol.task.schema.SendAllSchemasMessageTask; +import com.hazelcast.client.impl.protocol.task.schema.SendSchemaMessageTask; +import com.hazelcast.cp.internal.client.AddCPGroupAvailabilityListenerMessageTask; +import com.hazelcast.cp.internal.client.AddCPMembershipListenerMessageTask; +import com.hazelcast.cp.internal.client.RemoveCPGroupAvailabilityListenerMessageTask; +import com.hazelcast.cp.internal.client.RemoveCPMembershipListenerMessageTask; +import com.hazelcast.cp.internal.datastructures.spi.client.CreateRaftGroupMessageTask; +import com.hazelcast.sql.impl.client.SqlCloseMessageTask; +import com.hazelcast.sql.impl.client.SqlExecuteMessageTask; +import com.hazelcast.sql.impl.client.SqlFetchMessageTask; +import com.hazelcast.test.HazelcastParallelClassRunner; +import com.hazelcast.test.annotation.QuickTest; + +import javassist.ClassPool; +import javassist.NotFoundException; +import javassist.bytecode.BadBytecode; +import javassist.bytecode.ClassFile; +import javassist.bytecode.CodeAttribute; +import javassist.bytecode.CodeIterator; +import javassist.bytecode.MethodInfo; +import javassist.bytecode.Mnemonic; + +/** + * Verifies the {@code getRequiredPermission()} method doesn't simply return null in client {@link MessageTask} instances. + */ +@RunWith(HazelcastParallelClassRunner.class) +@Category({ QuickTest.class }) +public class MessageTaskSecurityTest { + + private static final String[] RETURN_NULL_OPS = { "aconst_null", "areturn" }; + private static final Map<String, String> SKIP_CLASS_MAP = new ConcurrentHashMap<>(); + + static { + skip(AddBackupListenerMessageTask.class, + "Adds listener called for every invocation for smart clients if backupAcks are enabled"); + skip(AddClusterViewListenerMessageTask.class, "Adds listener for listening to member list and partition table changes"); + skip(AddDistributedObjectListenerMessageTask.class, "Adds distributed object listener by user's request"); + skip(AddMigrationListenerMessageTask.class, "Adds an internal listener"); + skip(AddPartitionLostListenerMessageTask.class, "Adds an internal listener"); + skip(CacheFetchNearCacheInvalidationMetadataTask.class, "Internal task used by RepairingTask"); + skip(ClientStatisticsMessageTask.class, "Client statistics collection task"); + skip(ExperimentalAuthenticationMessageTask.class, "Beta-mode of TPC authentication"); + skip(GetDistributedObjectsMessageTask.class, "Gets proxies"); + skip(MapAddListenerMessageTask.class, "Permissions checked by subsequent MapPublisherCreate* tasks"); + skip(MapFetchNearCacheInvalidationMetadataTask.class, "Internal task used by RepairingTask"); + skip(MapMadePublishableMessageTask.class, "Internal task used by RepairingTask"); + skip(NoSuchMessageTask.class, "Fallback MessageTask type - no cluster action performed"); + skip(PingMessageTask.class, "Heart beat type - no cluster action performed"); + skip(RemoveDistributedObjectListenerMessageTask.class, "Removes distributed object listener by user's request"); + skip(RemoveMigrationListenerMessageTask.class, "Adds an internal listener"); + skip(RemovePartitionLostListenerMessageTask.class, "Adds an internal listener"); + skip(FetchSchemaMessageTask.class, "Fetch compact-serialization schema"); + skip(SendAllSchemasMessageTask.class, "Send compact-serialization schemas"); + skip(SendSchemaMessageTask.class, "Send a compact-serialization schema"); + skip(TriggerPartitionAssignmentMessageTask.class, "Triggers first partition arrangement"); + skip(AddCPGroupAvailabilityListenerMessageTask.class, "Listener for the cluster-topology change"); + skip(AddCPMembershipListenerMessageTask.class, "Listener for the cluster-topology change"); + skip(RemoveCPGroupAvailabilityListenerMessageTask.class, "Listener for the cluster-topology change"); + skip(RemoveCPMembershipListenerMessageTask.class, "Listener for the cluster-topology change"); + skip(CreateRaftGroupMessageTask.class, "Initial message while creating a Client proxy for any CP object"); + skip(SqlExecuteMessageTask.class, "Permissions for specific objects are checked based on parsed query text"); + skip(SqlCloseMessageTask.class, "Follow up SQL message where queryId is present"); + skip(SqlFetchMessageTask.class, "Follow up SQL message where queryId is present"); + skip(AuthenticationMessageTask.class, "Authentication message processing"); + skip(AuthenticationCustomCredentialsMessageTask.class, "Authentication message processing"); + skip(ExperimentalTpcAuthenticationMessageTask.class, "Authentication message processing"); + skip(ExperimentalAuthenticationCustomCredentialsMessageTask.class, "Authentication message processing"); + skip(CreateProxiesMessageTask.class, "Permissions handled in beforeProcess() method"); + } + + @Test + public void testGetRequiredPermissions() throws Exception { + Reflections reflections = new Reflections("com.hazelcast"); + Set<Class<? extends AbstractMessageTask>> subTypes = reflections.getSubTypesOf(AbstractMessageTask.class); + for (Class clazz : subTypes) { + if (!Modifier.isAbstract(clazz.getModifiers())) { + assertGetRequiredPermission(clazz.getName()); + } + } + } + + @Test + public void testCreateProxiesOverridesBeforeProcess() throws Exception { + assertNotNull(CreateProxiesMessageTask.class.getDeclaredMethod("beforeProcess")); + } + + private void assertGetRequiredPermission(String clsname) throws Exception { + if (SKIP_CLASS_MAP.containsKey(clsname)) { + return; + } + boolean returnsNull = doesGetRequiredPermissionSimpleReturnNull(clsname); + assertFalse(clsname + " returns null in getRequiredPermission()", returnsNull); + } + + private boolean doesGetRequiredPermissionSimpleReturnNull(String clsname) throws NotFoundException, Exception, BadBytecode { + if (clsname == null) { + fail("Class with getRequiredPermission() method implementation not found"); + } + ClassPool cp = ClassPool.getDefault(); + ClassFile cf = cp.get(clsname).getClassFile(); + MethodInfo minfo = cf.getMethod("getRequiredPermission"); + if (minfo == null) { + return doesGetRequiredPermissionSimpleReturnNull(cf.getSuperclass()); + } + CodeAttribute ca = minfo.getCodeAttribute(); + CodeIterator ci = ca.iterator(); + String[] ops = new String[RETURN_NULL_OPS.length]; + int i = 0; + while (ci.hasNext()) { + i++; + if (i > RETURN_NULL_OPS.length) { + return false; + } + int index = ci.next(); + int op = ci.byteAt(index); + ops[i - 1] = Mnemonic.OPCODE[op]; + } + return Arrays.equals(RETURN_NULL_OPS, ops); + } + + private static void skip(Class<?> classToSkip, String reason) { + Assertions.assertThat(reason).isNotEmpty(); + SKIP_CLASS_MAP.put(classToSkip.getName(), reason); + } +}
Vulnerability mechanics
Root cause
"Multiple client protocol message tasks returned null from getRequiredPermission(), causing the security framework to skip authorization checks for cache and map operations."
Attack vector
An authenticated Hazelcast client can send crafted client protocol messages for cache and map operations (iterate, destroy, load, listen, register listeners, create proxies) that lack proper permission checks. Because the affected message tasks returned `null` from `getRequiredPermission()`, the security framework skipped authorization entirely [CWE-281]. This allows an authenticated but low-privileged user to read, iterate, destroy, or listen to cache and map data they should not have access to, effectively bypassing the configured permission model [CWE-922]. The attacker only needs valid cluster credentials and network access to the Hazelcast cluster; no special configuration is required.
Affected code
The vulnerability spans multiple client protocol message tasks in the Hazelcast codebase. Files under `hazelcast/src/main/java/com/hazelcast/client/impl/protocol/task/` — including `cache/CacheIterateMessageTask.java`, `cache/CacheDestroyMessageTask.java`, `cache/CacheRemoveInvalidationListenerMessageTask.java`, `cache/CacheListenerRegistrationMessageTask.java`, `cache/CacheLoadAllMessageTask.java`, `cache/CacheAddNearCacheInvalidationListenerTask.java`, `map/MapPublisherCreateWithValueMessageTask.java`, `map/MapRemovePartitionLostListenerMessageTask.java`, and `CreateProxiesMessageTask.java` — all had `getRequiredPermission()` methods returning `null` instead of a proper permission object [patch_id=1640570].
What the fix does
The patch [patch_id=1640570] replaces `return null` in `getRequiredPermission()` with proper `Permission` objects (e.g., `CachePermission`, `MapPermission`) for each affected message task. For example, `CacheIterateMessageTask` now returns `new CachePermission(parameters.name, ActionConstants.ACTION_READ)`, and `MapPublisherCreateWithValueMessageTask` returns `new MapPermission(parameters.mapName, ActionConstants.ACTION_LISTEN)`. The `CreateProxiesMessageTask` takes a different approach: it overrides `beforeProcess()` to check create permissions per proxy object individually, since multiple permissions are needed. A new test class (`MessageTaskSecurityTest`) was added to verify that no concrete `AbstractMessageTask` subclass returns `null` from `getRequiredPermission()`, preventing regression. These changes ensure the security framework properly enforces authorization before executing client operations.
Preconditions
- authAttacker must have valid authentication credentials to the Hazelcast cluster.
- networkAttacker must have network access to the Hazelcast cluster endpoint.
- configNo special configuration is required; the bug exists in default permission setups.
Generated on May 23, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4News mentions
0No linked articles in our index yet.