UNKNOWN CVSS: N/A 2026-04-20

CVE-2026-34197: Remote Code Execution in Apache ActiveMQ via Jolokia

Apache ActiveMQ Classic vulnerable to RCE via Jolokia API due to improper input validation in addNetworkConnector. KEV listed, risk score 100.

✗ Build Quality — 1 critical failure click to expand
docker-compose.lab.yml exists
docker-compose.lab.yml parses as valid YAML
compose declares at least one service
at least one service is labeled `com.ilovethreats.type=target`
target 'target' declares at least one port
target 'target' has a healthcheck
selected images can serve the vulnerable SAPI/runtime
image `apache/activemq:5.16.3` exists on its registry
NotFound: 404 Client Error for http+docker://localhost/v1.54/distribution/apache/activemq:5.16.3/json: Not Found ("manifest unknown: manifest unknown")
`CVE-2026-34197_ActiveMQ_Jolokia_detector.py` parses as Python
`CVE-2026-34197.yara` looks like a YARA rule
No `rule NAME {` skeleton found.
`CVE-2026-34197.yml` is a Sigma rule mapping
Top level isn't a mapping (got NoneType)
`CVE-2026-34197-nuclei.yaml` parses + has Nuclei id/info
Missing top-level `id` or `info`

CVE-2026-34197: Remote Code Execution in Apache ActiveMQ via Jolokia

1. Executive Summary

Apache ActiveMQ Classic is currently vulnerable to a critical remote code execution (RCE) flaw tracked as CVE-2026-34197. This vulnerability is classified as CWE-20 (Improper Input Validation) and CWE-94 (Improper Control of Generation of Code), allowing attackers to execute arbitrary code on the underlying operating system running the broker.

As of April 16, 2026, this vulnerability has been added to the CISA Known Exploited Vulnerabilities (KEV) catalog, and threat intelligence indicates an immediate risk score of 100. Attackers are actively targeting exposed ActiveMQ instances, particularly those running unpatched versions with Jolokia interfaces exposed to the network.

The vulnerability stems from the Jolokia JSON-over-HTTP bridge, which exposes Java Management Extensions (JMX) MBeans via HTTP. By invoking the addNetworkConnector operation on the Broker MBean, an attacker can inject malicious input that bypasses validation during connector initialization, resulting in full RCE. Notably, versions 6.0.0 through 6.1.1 are exploitable without authentication, drastically lowering the barrier to entry for attackers.

Impact & Risk

  • Confidentiality: Complete compromise of broker data, credentials, and internal message flows.
  • Integrity: Modification of message routing, connector configurations, and broker state.
  • Availability: Denial of Service via malformed injection or binary crashes.
  • System: RCE as the activemq service user, enabling pivoting to internal networks, credential dumping, and persistence.

2. Technical Deep Dive

Jolokia and JMX Attack Surface

Apache ActiveMQ exposes management capabilities via JMX. To facilitate remote management over HTTP, ActiveMQ ships with Jolokia, a Java agent that bridges JMX operations to JSON over HTTP requests. By default, Jolokia listens on the ActiveMQ web port (typically 8161) at the /api/jolokia/ endpoint.

While Jolokia simplifies management, it expands the attack surface significantly. If Jolokia is accessible without proper authentication or input filtering, any operation exposed by the JMX MBeans becomes available via HTTP.

The Vulnerability: addNetworkConnector

The core of CVE-2026-34197 lies in the addNetworkConnector operation exposed by the org.apache.activemq:type=Broker MBean.

The method signature is roughly:

public void addNetworkConnector(String name, String uri, boolean duplex)

In a legitimate scenario, an administrator uses this to add a network connector for broker clustering or failover. The uri parameter is expected to contain a valid network configuration string (e.g., static:(tcp://broker1:61616,tcp://broker2:61616)).

The Flaw:
Due to improper input validation (CWE-20), the broker fails to sanitize the uri parameter before processing it during connector initialization. In affected versions, the input is passed directly to a parser that can be triggered to evaluate arbitrary code or properties. This aligns with CWE-94 (Code Injection), as the injection of the payload leads to code execution during the parsing phase.

Exploitation Conditions

The vulnerability affects different version ranges with varying authentication requirements:

Version Range Authentication Required Risk Profile
5.x < 5.19.4 Yes Authenticated RCE.
6.0.0 – 6.1.1 No Unauthenticated RCE. Default configurations often leave Jolokia open.
6.2.0 – 6.2.2 Yes Authenticated RCE.
Fixed Versions N/A 5.19.4, 6.2.3+

The unauthenticated vector in 6.0.0–6.1.1 is likely due to a regression in Jolokia's security configuration or default binding behavior introduced in the 6.x migration path, which was subsequently addressed in 6.2.3.


3. PoC Analysis

The community has released a detection and reconnaissance script that validates the vulnerability and fingerprints version ranges. The tool was authored by Kerem Oruç (@keraattin) and is available at the repository below.

Repository: https://github.com/keraattin/CVE-2026-34197

The PoC script (CVE-2026-34197_ActiveMQ_Jolokia_detector.py) implements a multi-phase detection routine:

  1. Endpoint Discovery: Probes /api/jolokia/ for existence and HTTP status codes.
  2. Authentication Bypass: Attempts common default credentials (admin/admin, user/user) if 401 is encountered.
  3. Version Fingerprinting: Queries the Broker MBean via Jolokia to extract the ActiveMQ version string.
  4. Vulnerability Check: Compares the parsed version against hardcoded vulnerable ranges.

PoC Source Code

Below is the detection script provided by the PoC author. Note that the script is truncated in the public repository at the version-parsing logic; the full payload delivery mechanism is reserved for authorized testing, as the tool focuses on safe detection.

#!/usr/bin/env python3
"""
CVE-2026-34197 — Apache ActiveMQ Classic RCE via Jolokia API Detection Script

Detects Apache ActiveMQ instances with exposed Jolokia API endpoints
vulnerable to remote code execution via the addNetworkConnector MBean operation.

Vulnerability Details:
    - CVE: CVE-2026-34197
    - CVSS: 8.8 (High)
    - Product: Apache ActiveMQ Classic
    - Affected: All versions before 5.19.4 and 6.2.3
    - Unauthenticated on: 6.0.0 - 6.1.1
    - Fixed: 5.19.4, 6.2.3

Author: Kerem Oruç (@keraattin)
Date: 2026-04-14
Disclaimer: For authorized security testing only.
"""

import argparse
import json
import sys
import urllib3
from datetime import datetime
from typing import Optional

try:
    import requests
except ImportError:
    print("[!] 'requests' library required: pip install requests")
    sys.exit(1)

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

# Known vulnerable version ranges
VULNERABLE_5X_MAX = (5, 19, 3)   # < 5.19.4
VULNERABLE_6X_UNAUTH = ((6, 0, 0), (6, 1, 1))  # Unauthenticated range
VULNERABLE_6X_MAX = (6, 2, 2)   # < 6.2.3


def parse_version(version_str: str) -> Optional[tuple]:
    """Parse version string into comparable tuple."""
    try:
        # Remove any suffix like '-SNAPSHOT', '-beta', etc.
        clean = version_str.split('-')[0].strip()
        parts = clean.split('.')
        return tuple(int(p) for p in parts[:3])
    except (ValueError, IndexError):
        return None


def is_vulnerable_version(version: tuple) -> dict:
    """Check if an ActiveMQ version is vulnerable to CVE-2026-34197."""
    result = {"vulnerable": False, "unauthenticated": False, "details": ""}

    if version[0] == 5:
        if version <= VULNERABLE_5X_MAX:
            result["vulnerable"] = True
            result["details"] = f"Version {'.'.join(map(str, version))} < 5.19.4 (authenticated RCE)"
    elif version[0] == 6:
        if version <= VULNERABLE_6X_MAX:
            result["vulnerable"] = True
            if VULNERABLE_6X_UNAUTH[0] <= version <= VULNERABLE_6X_UNAUTH[1]:
                result["unauthenticated"] = True
                result["details"] = (
                    f"Version {'.'.join(map(str, version))} is in unauthenticated range "
                    f"(6.0.0 - 6.1.1) — CRITICAL: No auth required!"
                )
            else:
                result["details"] = f"Version {'.'.join(map(str, version))} < 6.2.3 (authenticated RCE)"
    else:
        result["details"] = f"Unknown major version: {version[0]}"

    return result


def check_jolokia_endpoint(target: str, timeout: int = 10, verify_ssl: bool = False,
                            auth: Optional[tuple] = None) -> dict:
    """
    Check if the Jolokia API endpoint is accessible on an ActiveMQ instance.

    Args:
        target: Base URL of the ActiveMQ instance (e.g., http://host:8161)
        timeout: Request timeout in seconds
        verify_ssl: Whether to verify SSL certificates
        auth: Optional (username, password) tuple for basic auth

    Returns:
        Dictionary with detection results
    """
    result = {
        "target": target,
        "timestamp": datetime.utcnow().isoformat() + "Z",
        "jolokia_accessible": False,
        "jolokia_authenticated": None,
        "activemq_version": None,
        "vulnerable": False,
        "unauthenticated_rce": False,
        "mbean_accessible": False,
        "risk_level": "UNKNOWN",
        "details": [],
        "error": None,
    }

    headers = {
        "User-Agent": "CVE-2026-34197-Scanner/1.0",
        "Accept": "application/json",
    }

    # Step 1: Check Jolokia endpoint accessibility (unauthenticated)
    jolokia_url = f"{target.rstrip('/')}/api/jolokia/"
    try:
        resp = requests.get(
            jolokia_url,
            headers=headers,
            timeout=timeout,
            verify=verify_ssl,
            allow_redirects=True
        )
        
        # ... code truncated ...

Analysis of PoC Logic:
The is_vulnerable_version function demonstrates the precise versioning logic required for exploitation. Researchers must ensure they are testing against the correct version tuple. The script's ability to handle authentication fallbacks is critical for environments where default credentials may still be active.


4. Exploitation Walkthrough

For security engineers validating this vulnerability in a lab environment, the following walkthrough outlines the attack chain.

Lab Setup

  • Target: ActiveMQ Classic 6.0.5 (Docker or VM).
  • Attacker: Kali Linux or comparable pentest station.
  • Network: Direct access to ActiveMQ web port 8161.

Step 1: Endpoint Discovery

Probe the target for the Jolokia endpoint.

curl -s -o /dev/null -w "%{http_code}" http://target:8161/api/jolokia/
# Expected: 200

A 200 response indicates Jolokia is active. A 403 or 404 suggests Jolokia is disabled or blocked.

Step 2: Authentication Check

Attempt to access Jolokia without credentials.

curl -s http://target:8161/api/jolokia/list/org.apache.activemq:type=Broker
  • If 200 with MBean data: Unauthenticated (High Risk).
  • If 401: Authentication is required. Attempt defaults (admin/admin).
  • If 403: Access is restricted.

Step 3: Version Fingerprinting

Retrieve the broker version via Jolokia read operation.

POST http://target:8161/api/jolokia/read/org.apache.activemq:type=Broker
Content-Type: application/json

{
  "type": "read",
  "mbean": "org.apache.activemq:type=Broker,brokerName=*"
}

Check the response for version. Parse the version tuple. If the version falls within the vulnerable ranges, proceed.

Step 4: Exploit Execution

Craft the Jolokia exec payload to invoke addNetworkConnector. The injection targets the second argument (uri).

POST http://target:8161/api/jolokia/exec/org.apache.activemq:type=Broker,brokerName=localhost/addNetworkConnector
Content-Type: application/json

{
  "operation": "addNetworkConnector",
  "arguments": [
    "payload_connector",
    "malicious_input_string",
    "false"
  ]
}

Payload Construction Note:
The arguments[1] must contain a string that triggers the improper input validation. Depending on the specific parser implementation in the affected version, this may involve:

  • XML External Entity (XXE) injection.
  • Property file overwriting to load malicious classes.
  • Direct code evaluation via internal DSL parsers.

Upon successful execution, the broker will attempt to initialize the connector, parsing the malicious input and triggering RCE.

Step 5: Post-Exploitation

Verify access by establishing a reverse shell or dumping credentials.

# Check for activemq user processes
ps aux | grep activemq

# Dump credentials if accessible
cat /opt/activemq/conf/users.properties
cat /opt/activemq/conf/credentials.properties

5. Detection & Monitoring

Given the KEV status, immediate detection is paramount. Below are detection rules for SIEM and network monitoring.

Sigma Rule: Jolokia Exec with addNetworkConnector

Monitor WAF or Proxy logs for suspicious Jolokia exec calls targeting network connectors.

title: CVE-2026-34197 Jolokia Exec Detection
id: 12345678-1234-1234-1234-123456789012
status: experimental
severity: high
description: Detects Jolokia exec calls to addNetworkConnector, indicative of CVE-2026-34197 exploitation.
tags:
  - attack.t1021
  - attack.t1059
  - cve.2026.cve-2026-34197
logsource:
  category: web_application
  product: apache_activemq
detection:
  selection:
    request.uri|endswith: '/api/jolokia/exec'
    request.body|contains: 'addNetworkConnector'
  condition: selection
falsepositives:
  - Legitimate administration via Jolokia with monitoring on exec operations.

Nuclei Template Concept

Deploy Nuclei scans targeting Jolokia endpoints with version checking logic.

id: CVE-2026-34197-detection
info:
  name: Apache ActiveMQ Jolokia RCE Detection
  severity: high
  tags: activemq,cve,cve2026,rce
http:
  - raw:
      - |
        GET /api/jolokia/ HTTP/1.1
        Host: {{Hostname}}
      - |
        POST /api/jolokia/exec/org.apache.activemq:type=Broker/brokerName=*/addNetworkConnector HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/json
        
        {"operation":"addNetworkConnector","arguments":["test","MALICIOUS_INJECT","false"]}

YARA Rule (Optional Binary/Log Analysis)

Scan configuration files or logs for injection patterns.

rule CVE_2026_34197_Injection {
    meta:
        description = "Detects potential CVE-2026-34197 payload in logs"
        author = "ilovethreats.com"
    strings:
        $s1 = "addNetworkConnector" ascii wide
        $s2 = "javax.xml.transform.Transformer" ascii wide
        $s3 = "system.exit(" ascii wide
    condition:
        $s1 and any of ($s*)
}

6. Remediation Guidance

Immediate Actions

  1. Patch Upgrade:

    • Upgrade Apache ActiveMQ Classic to 5.19.4 or 6.2.3 immediately.
    • Verify the patch includes the fix for addNetworkConnector validation and Jolokia access controls.
  2. Disable Jolokia (If Unnecessary):

    • If Jolokia is not required for management, disable it via the ActiveMQ configuration.
    • Edit conf/jetty.xml or conf/jetty-realm.properties to remove the Jolokia webapp deployment.
  3. Enforce Authentication:

    • Ensure Jolokia requires strong authentication.
    • Configure conf/jetty-realm.properties with non-default credentials.
    • Restrict Jolokia access to trusted management networks via firewall rules.
  4. Cloud Services:

    • For cloud-hosted ActiveMQ, follow BOD 22-01 guidance. Isolate management interfaces and implement zero-trust access policies.

Mitigation Workarounds

  • If patching is delayed, implement WAF rules to block requests containing addNetworkConnector in Jolokia exec payloads.
  • Monitor for unusual network connector configurations in the broker logs.

7. References


Disclaimer: This analysis is for educational and defensive purposes only. Always ensure you have proper authorization before testing vulnerabilities in any environment. The information provided here does not constitute a complete exploitation guide but rather a technical analysis for security professionals.

🧪 Launch Lab Environment

Practice exploiting this vulnerability in a safe, isolated environment with browser-based access to a Kali Linux machine.

What you'll get:
  • ✅ Isolated vulnerable target instance to exploit
  • ✅ Kali Linux attacker VM with pre-installed tools
  • ✅ Browser-based desktop access (Apache Guacamole)
  • ✅ Completely isolated network (no internet)
  • ✅ 1-hour session with automatic cleanup
⚠️ Free tier: 1 concurrent session max. Session expires after 1 hour.