CVE-2026-33701
Description
OpenTelemetry Java Instrumentation provides OpenTelemetry auto-instrumentation and instrumentation libraries for Java. In versions prior to 2.26.1, the RMI instrumentation registered a custom endpoint that deserialized incoming data without applying serialization filters. On JDK version 16 and earlier, an attacker with network access to a JMX or RMI port on an instrumented JVM could exploit this to potentially achieve remote code execution. All three of the following conditions must be true to exploit this vulnerability: First, OpenTelemetry Java instrumentation is attached as a Java agent (-javaagent) on Java 16 or earlier. Second, JMX/RMI port has been explicitly configured via -Dcom.sun.management.jmxremote.port and is network-reachable. Third, gadget-chain-compatible library is present on the classpath. This results in arbitrary remote code execution with the privileges of the user running the instrumented JVM. For JDK >= 17, no action is required, but upgrading is strongly encouraged. For JDK < 17, upgrade to version 2.26.1 or later. As a workaround, set the system property -Dotel.instrumentation.rmi.enabled=false to disable the RMI integration.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
io.opentelemetry.javaagent:opentelemetry-javaagentMaven | < 2.26.1 | 2.26.1 |
Affected products
1- cpe:2.3:a:linuxfoundation:opentelemetry_instrumentation_for_java:*:*:*:*:*:*:*:*Range: <2.26.1
Patches
19cf4fbaaa9e7Fix RMI context propagation (#16979)
11 files changed · +53 −28
CHANGELOG.md+7 −0 modified@@ -1,5 +1,12 @@ # Changelog +## Version 2.26.1 (2026-03-23) + +### 🛠️ Bug fixes + +- Fix RMI context propagation + ([#16979](https://github.com/open-telemetry/opentelemetry-java-instrumentation/pull/16979)) + ## Version 2.26.0 (2026-03-13) ### ⚠️ Breaking changes to non-stable APIs
docs/apidiffs/current_vs_latest/opentelemetry-instrumentation-annotations.txt+1 −1 modified@@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-instrumentation-annotations-2.26.0.jar against opentelemetry-instrumentation-annotations-2.25.0.jar +Comparing source compatibility of opentelemetry-instrumentation-annotations-2.26.1.jar against opentelemetry-instrumentation-annotations-2.25.0.jar No changes. \ No newline at end of file
docs/apidiffs/current_vs_latest/opentelemetry-instrumentation-api.txt+1 −1 modified@@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-instrumentation-api-2.26.0.jar against opentelemetry-instrumentation-api-2.25.0.jar +Comparing source compatibility of opentelemetry-instrumentation-api-2.26.1.jar against opentelemetry-instrumentation-api-2.25.0.jar No changes. \ No newline at end of file
docs/apidiffs/current_vs_latest/opentelemetry-spring-boot-autoconfigure.txt+1 −1 modified@@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-spring-boot-autoconfigure-2.26.0.jar against opentelemetry-spring-boot-autoconfigure-2.25.0.jar +Comparing source compatibility of opentelemetry-spring-boot-autoconfigure-2.26.1.jar against opentelemetry-spring-boot-autoconfigure-2.25.0.jar No changes. \ No newline at end of file
docs/apidiffs/current_vs_latest/opentelemetry-spring-boot-starter.txt+1 −1 modified@@ -1,2 +1,2 @@ -Comparing source compatibility of opentelemetry-spring-boot-starter-2.26.0.jar against opentelemetry-spring-boot-starter-2.25.0.jar +Comparing source compatibility of opentelemetry-spring-boot-starter-2.26.1.jar against opentelemetry-spring-boot-starter-2.25.0.jar No changes. \ No newline at end of file
examples/distro/build.gradle+3 −3 modified@@ -14,7 +14,7 @@ buildscript { dependencies { classpath "com.diffplug.spotless:spotless-plugin-gradle:8.3.0" classpath "com.gradleup.shadow:shadow-gradle-plugin:9.3.2" - classpath "io.opentelemetry.instrumentation:gradle-plugins:2.26.0-alpha" + classpath "io.opentelemetry.instrumentation:gradle-plugins:2.26.1-alpha" } } @@ -30,8 +30,8 @@ subprojects { opentelemetrySdk : "1.60.1", // these lines are managed by .github/scripts/update-version.sh - opentelemetryJavaagent : "2.26.0", - opentelemetryJavaagentAlpha: "2.26.0-alpha", + opentelemetryJavaagent : "2.26.1", + opentelemetryJavaagentAlpha: "2.26.1-alpha", autoservice : "1.1.1" ]
examples/extension/build.gradle+4 −4 modified@@ -13,8 +13,8 @@ plugins { id "com.gradleup.shadow" version "9.3.2" id "com.diffplug.spotless" version "8.3.0" - id "io.opentelemetry.instrumentation.muzzle-generation" version "2.26.0-alpha" - id "io.opentelemetry.instrumentation.muzzle-check" version "2.26.0-alpha" + id "io.opentelemetry.instrumentation.muzzle-generation" version "2.26.1-alpha" + id "io.opentelemetry.instrumentation.muzzle-check" version "2.26.1-alpha" } group 'io.opentelemetry.example' @@ -26,8 +26,8 @@ ext { opentelemetrySdk : "1.60.1", // these lines are managed by .github/scripts/update-version.sh - opentelemetryJavaagent : "2.26.0", - opentelemetryJavaagentAlpha: "2.26.0-alpha" + opentelemetryJavaagent : "2.26.1", + opentelemetryJavaagentAlpha: "2.26.1-alpha" ] deps = [
instrumentation/rmi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rmi/context/ContextPayload.java+31 −13 modified@@ -17,11 +17,13 @@ import java.util.HashMap; import java.util.Map; import java.util.logging.Logger; +import javax.annotation.Nullable; /** ContextPayload wraps context information shared between client and server. */ public class ContextPayload { private static final Logger logger = Logger.getLogger(ContextPayload.class.getName()); + private static final int MAX_CONTEXT_ENTRIES = 1000; private final Map<String, String> context; @@ -41,24 +43,40 @@ public static ContextPayload from(Context context) { return payload; } - @SuppressWarnings("BanSerializableRead") // fine + @Nullable public static ContextPayload read(ObjectInput oi) throws IOException { - try { - Object object = oi.readObject(); - if (object instanceof Map) { - @SuppressWarnings("unchecked") // convert it back to the expected type - Map<String, String> map = (Map<String, String>) object; - return new ContextPayload(map); - } - } catch (ClassCastException | ClassNotFoundException ex) { - logger.log(FINE, "Error reading object", ex); + int size = oi.readInt(); + if (size > MAX_CONTEXT_ENTRIES) { + logger.log( + FINE, + "RMI context propagation payload size {0} exceeds maximum allowed of {1}, skipping context propagation.", + new Object[] {size, MAX_CONTEXT_ENTRIES}); + return null; } - - return null; + Map<String, String> map = new HashMap<>(); + for (int i = 0; i < size; i++) { + String key = oi.readUTF(); + String value = oi.readUTF(); + map.put(key, value); + } + return new ContextPayload(map); } public void write(ObjectOutput out) throws IOException { - out.writeObject(context); + int size = context.size(); + if (size > MAX_CONTEXT_ENTRIES) { + logger.log( + FINE, + "RMI context propagation payload size {0} exceeds maximum allowed of {1}, skipping context propagation.", + new Object[] {size, MAX_CONTEXT_ENTRIES}); + out.writeInt(0); + return; + } + out.writeInt(size); + for (Map.Entry<String, String> entry : context.entrySet()) { + out.writeUTF(entry.getKey()); + out.writeUTF(entry.getValue()); + } } public Context extract() {
instrumentation/rmi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rmi/context/ContextPropagator.java+1 −1 modified@@ -32,7 +32,7 @@ public class ContextPropagator { // RMI object id used to identify agent instrumentation public static final ObjID CONTEXT_CALL_ID = - new ObjID("io.opentelemetry.javaagent.context-call".hashCode()); + new ObjID("io.opentelemetry.javaagent.context-call-v2".hashCode()); // Operation id used for checking context propagation is possible // RMI expects these operations to have negative identifier, as positive ones mean legacy
README.md+1 −1 modified@@ -33,7 +33,7 @@ If you are looking for documentation on using those. ## Getting Started Download -the [latest version](https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v2.26.0/opentelemetry-javaagent.jar). +the [latest version](https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v2.26.1/opentelemetry-javaagent.jar). This package includes the instrumentation agent as well as instrumentations for all supported libraries and all available data exporters.
version.gradle.kts+2 −2 modified@@ -1,5 +1,5 @@ -val stableVersion = "2.26.0" -val alphaVersion = "2.26.0-alpha" +val stableVersion = "2.26.1" +val alphaVersion = "2.26.1-alpha" allprojects { if (findProperty("otel.stable") != "true") {
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- github.com/open-telemetry/opentelemetry-java-instrumentation/commit/9cf4fbaaa9e79226142b2ed42a6f6b4ac0be2197nvdPatchWEB
- github.com/advisories/GHSA-xw7x-h9fj-p2c7ghsaADVISORY
- github.com/open-telemetry/opentelemetry-java-instrumentation/security/advisories/GHSA-xw7x-h9fj-p2c7nvdMitigationVendor AdvisoryWEB
- nvd.nist.gov/vuln/detail/CVE-2026-33701ghsaADVISORY
- github.com/open-telemetry/opentelemetry-java-instrumentation/releases/tag/v2.26.1nvdRelease NotesWEB
News mentions
0No linked articles in our index yet.