This is an automated email from the ASF dual-hosted git repository.

tomsun28 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hertzbeat.git


The following commit(s) were added to refs/heads/master by this push:
     new 3496ebf497 [fix] fixed the JMX service URL validation issue (#4146)
3496ebf497 is described below

commit 3496ebf497163768eddfe4cfc1174ca26c2916d3
Author: Duansg <[email protected]>
AuthorDate: Thu May 28 09:39:54 2026 +0800

    [fix] fixed the JMX service URL validation issue (#4146)
---
 .../collector/collect/jmx/JmxCollectImpl.java      | 31 +++++++++++++++-------
 .../collector/collect/jmx/JmxCollectImplTest.java  | 23 +++++++++++++++-
 2 files changed, 44 insertions(+), 10 deletions(-)

diff --git 
a/hertzbeat-collector/hertzbeat-collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/jmx/JmxCollectImpl.java
 
b/hertzbeat-collector/hertzbeat-collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/jmx/JmxCollectImpl.java
index 2995469877..1266cac69d 100644
--- 
a/hertzbeat-collector/hertzbeat-collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/jmx/JmxCollectImpl.java
+++ 
b/hertzbeat-collector/hertzbeat-collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/jmx/JmxCollectImpl.java
@@ -18,9 +18,11 @@
 package org.apache.hertzbeat.collector.collect.jmx;
 
 import java.io.IOException;
+import java.net.MalformedURLException;
 import java.util.Arrays;
 import java.util.Date;
 import java.util.HashMap;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
@@ -106,31 +108,42 @@ public class JmxCollectImpl extends AbstractCollect {
     }
 
     /**
-     * Validate JMX URL 
-     * 
+     * Validate JMX URL
+     *
      * @param url JMX URL to validate
      * @throws IllegalArgumentException if URL is potentially malicious
      */
     private void validateJmxUrl(String url) throws IllegalArgumentException {
-        // Only allow service:jmx:rmi protocol
-        Assert.isTrue(url.startsWith("service:jmx:rmi:"), "Only 
service:jmx:rmi protocol is supported");
+        JMXServiceURL serviceUrl;
+        try {
+            serviceUrl = new JMXServiceURL(url);
+        } catch (MalformedURLException e) {
+            throw new IllegalArgumentException("Invalid JMX URL", e);
+        }
+        Assert.isTrue("rmi".equalsIgnoreCase(serviceUrl.getProtocol()), "Only 
service:jmx:rmi protocol is supported");
 
-        String[] disallowedPatterns = { "ldap:", "rmi:", "iiop:", "nis:", 
"dns:", "corbaname:", "http:", "https:" };
+        String lowerUrl = url.toLowerCase(Locale.ROOT);
+        String[] disallowedPatterns = {"ldap:", "iiop:", "nis:", "dns:", 
"corbaname:", "http:", "https:"};
         for (String pattern : disallowedPatterns) {
-            if (url.contains(pattern) && !pattern.equals("rmi:///jndi/rmi:")) {
+            if (lowerUrl.contains(pattern)) {
                 throw new IllegalArgumentException("Potentially unsafe JNDI 
protocol detected in URL: " + pattern);
             }
         }
 
+        String lowerPath = serviceUrl.getURLPath().toLowerCase(Locale.ROOT);
+        if (lowerPath.startsWith("/jndi/") && 
!lowerPath.startsWith("/jndi/rmi://")) {
+            throw new IllegalArgumentException("Only rmi JNDI protocol is 
supported");
+        }
+
         // Check for suspicious patterns
-        if (url.contains("${") || url.contains("$[") || url.contains(":#") || 
url.contains(":/")) {
+        if (url.contains("${") || url.contains("$[") || url.contains(":#")) {
             throw new IllegalArgumentException("Potentially malicious pattern 
detected in JMX URL");
         }
     }
 
     /**
-     * Validate hostname format 
-     * 
+     * Validate hostname format
+     *
      * @param hostname Hostname to validate
      * @return true if hostname is valid
      */
diff --git 
a/hertzbeat-collector/hertzbeat-collector-basic/src/test/java/org/apache/hertzbeat/collector/collect/jmx/JmxCollectImplTest.java
 
b/hertzbeat-collector/hertzbeat-collector-basic/src/test/java/org/apache/hertzbeat/collector/collect/jmx/JmxCollectImplTest.java
index 152ba296d4..539d600ab6 100644
--- 
a/hertzbeat-collector/hertzbeat-collector-basic/src/test/java/org/apache/hertzbeat/collector/collect/jmx/JmxCollectImplTest.java
+++ 
b/hertzbeat-collector/hertzbeat-collector-basic/src/test/java/org/apache/hertzbeat/collector/collect/jmx/JmxCollectImplTest.java
@@ -50,7 +50,7 @@ class JmxCollectImplTest {
             JmxProtocol jmx = JmxProtocol.builder().build();
             jmx.setUrl("/stub/");
             Metrics metrics = Metrics.builder().jmx(jmx).build();
-            
+
             jmxCollect.preCheck(metrics);
         });
     }
@@ -68,4 +68,25 @@ class JmxCollectImplTest {
     void supportProtocol() {
         assert 
DispatchConstants.PROTOCOL_JMX.equals(jmxCollect.supportProtocol());
     }
+
+    @Test
+    void preCheckShouldAcceptSupportedJmxRmiUrl() {
+        JmxProtocol jmx = JmxProtocol.builder()
+            .url("service:jmx:rmi:///jndi/rmi://127.0.0.1:9999/jmxrmi")
+            .build();
+        Metrics metrics = Metrics.builder().jmx(jmx).build();
+
+        assertDoesNotThrow(() -> jmxCollect.preCheck(metrics));
+    }
+
+    @Test
+    void preCheckShouldRejectUnsafeJndiProtocolInJmxRmiUrl() {
+        JmxProtocol jmx = JmxProtocol.builder()
+            .url("service:jmx:rmi:///jndi/ldap://127.0.0.1:1389/jmxrmi";)
+            .build();
+        Metrics metrics = Metrics.builder().jmx(jmx).build();
+
+        assertThrows(IllegalArgumentException.class, () -> 
jmxCollect.preCheck(metrics));
+    }
+
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to