September 1, 2020·4 min read·engineeringcassandrasecurityjmx

Cassandra JMX credentials depend on the RMI registry

CVE-2020-13946 allows interception of Cassandra JMX credentials through registry manipulation. The disclosure and fixed implementation explain why management authentication needs a trustworthy lookup path.

A password protects a management connection only if the client sends it to the intended server. The Cassandra advisory for CVE-2020-13946 describes an attack against that assumption. A local attacker can manipulate the RMI registry and intercept the usernames and passwords used to access JMX. The attacker does not need access to the Cassandra process or its configuration files to carry out the registry manipulation described in the advisory.

Sam Tunnicliffe published the original disclosure on September 1, 2020. The CVE record identifies the same credential-interception issue. Its consequence is access to the JMX interface using captured credentials, with the ability to perform unauthorised operations. This is an administrative-interface vulnerability, so understanding it requires looking beyond authentication of ordinary CQL requests.

I find Cassandra compelling for applications that require its distributed operation. That makes the management interface part of the system I need to understand. Its credentials grant authority over database operations, and their security depends on the connection machinery that locates the management server.

The registry is part of establishing trust

The JMX server implementation in Cassandra 3.11.8 creates an RMI registry with the lookup name jmxrmi. It separately constructs the RMI server and the JMX connector server. After starting the connector, it supplies the server stub to the registry through an internal setter.

That division explains why the registry matters. Locating the remote object and authenticating to the JMX server are different steps in the implementation. Protecting an authentication exchange requires a trustworthy way to obtain the object to which the client connects. The advisory identifies registry manipulation as the point that can redirect that exchange.

The registry in the fixed version subclasses the JRE registry implementation. Its lookup method returns the configured server stub for the expected name. Its list method exposes that name. The bind, unbind and rebind methods have empty implementations, so those entry points do not change the stored server reference.

The internal setter remains available to the Cassandra setup code. This gives startup a way to install the server stub without making remote registry mutation the normal mechanism for changing it. The distinction is visible in the source itself. The registry can answer the lookup needed by clients while its exposed mutation methods do not modify the reference.

This describes the implementation shipped in a fixed release. It does not establish that every line in the class first appeared in that release, nor that registry behaviour is the only security-relevant difference across the maintained branches. The public advisory supplies the supported upgrade destinations. The source helps explain the role of the registry without replacing that version guidance.

Authentication and authorisation are separate decisions

The same class configures JMX authentication through an environment map. If the authentication system property is false, it returns without installing an authenticator. When authentication is enabled, a configured JAAS login entry takes precedence. Otherwise the code uses a wrapper around the JDK file-based authenticator, with support for a configured password-file location.

Those options determine how the server checks the credentials it receives. They do not by themselves establish that the client reached the intended server before submitting them. That is the connection between this code and the credential-interception advisory. Stronger verification at the destination cannot prevent disclosure to a different destination chosen through an untrusted lookup.

Authorisation has its own configuration path. The implementation can install a custom proxy, including the Cassandra role-based authorisation helper, or specify the standard JMX access file. The code comments state that neither method being configured means no access control is applied by that path. Successful authentication and permission to perform a management action are therefore distinct configuration questions.

This matters when describing the impact of stolen credentials. The advisory says an attacker can use them for unauthorised operations. The exact set of operations available to a particular identity depends on how that installation configures management authorisation. It would be inaccurate to infer an identical permission set for every JMX user from the existence of the vulnerability.

Local exposure still needs a host trust model

The 3.11.8 environment configuration defaults LOCAL_JMX to yes when unset. In that branch it configures the local JMX port and disables JMX authentication. The remote branch enables authentication and exposes commented options for SSL configuration. The file also warns against exposing the management port to the internet.

These defaults describe different trust assumptions. A local-only interface assumes that access to the host already conveys relevant authority. The advisory specifically describes a local attacker who lacks access to Cassandra itself, which makes the distinction between host access and database access material. Restricting a service to local connections does not establish that every local process belongs to the database operator.

The disclosure also warns about CVE-2019-2684, a JRE vulnerability that can enable remote exploitation of this issue. That warning prevents treating the local-attack description as a complete statement about every runtime combination. The Cassandra and JRE conditions have to be considered together when assessing the disclosed exposure.

The advisory gives branch-specific destinations

The September disclosure directs 2.1 users to 2.1.22 and 2.2 users to 2.2.18. It names 3.0.22 for the 3.0 line and 3.11.8 for the 3.11 line. Users testing 4.0-beta1 are directed to 4.0-beta2. Those are the fixed destinations stated in the original announcement, not versions inferred from a later support matrix.

I regard the connection setup as part of the authentication design because the client must locate the server before the server can validate a password. In the fixed implementation, the registry exposes its expected lookup while its binding mutation methods do not alter the stored reference. The advisory supplies the upgrade path for each affected Cassandra branch and explicitly adds the JRE condition to the exposure assessment.