You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@eventmesh.apache.org by mx...@apache.org on 2023/11/23 05:55:56 UTC

(eventmesh) branch master updated: [ISSUE #4564] add url validation to avoid SSRF (#4572)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new df288ab70 [ISSUE #4564] add url validation to avoid SSRF (#4572)
df288ab70 is described below

commit df288ab70155503d81c9467b50241371f102a454
Author: wizardzhang <wi...@126.com>
AuthorDate: Thu Nov 23 13:55:51 2023 +0800

    [ISSUE #4564] add url validation to avoid SSRF (#4572)
    
    * [ISSUE #4564]
    add url validation to avoid SSRF
    
    * [ISSUE #4564] correct log level
---
 build.gradle                                               |  2 ++
 eventmesh-runtime/build.gradle                             |  2 ++
 .../org/apache/eventmesh/runtime/util/WebhookUtil.java     | 14 ++++++++++++++
 .../org/apache/eventmesh/runtime/util/WebhookUtilTest.java | 14 +++++++++++++-
 4 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/build.gradle b/build.gradle
index 99aaf4e09..798e5ad5f 100644
--- a/build.gradle
+++ b/build.gradle
@@ -482,6 +482,8 @@ subprojects {
 
             dependency "commons-io:commons-io:2.11.0"
 
+            dependency "commons-validator:commons-validator:1.7"
+
             dependency "com.google.guava:guava:31.0.1-jre"
 
             dependency "org.slf4j:slf4j-api:1.7.30"
diff --git a/eventmesh-runtime/build.gradle b/eventmesh-runtime/build.gradle
index a7fc97018..871ce8cbe 100644
--- a/eventmesh-runtime/build.gradle
+++ b/eventmesh-runtime/build.gradle
@@ -33,6 +33,8 @@ dependencies {
 
     implementation "commons-io:commons-io"
 
+    implementation "commons-validator:commons-validator"
+
     implementation project(":eventmesh-common")
     implementation project(":eventmesh-spi")
     implementation project(":eventmesh-storage-plugin:eventmesh-storage-api")
diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/WebhookUtil.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/WebhookUtil.java
index 38a418e4b..1203184a8 100644
--- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/WebhookUtil.java
+++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/WebhookUtil.java
@@ -22,6 +22,7 @@ import org.apache.eventmesh.common.utils.LogUtils;
 import org.apache.eventmesh.spi.EventMeshExtensionFactory;
 
 import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.validator.routines.UrlValidator;
 import org.apache.http.client.methods.CloseableHttpResponse;
 import org.apache.http.client.methods.HttpOptions;
 import org.apache.http.client.methods.HttpPost;
@@ -49,12 +50,21 @@ public class WebhookUtil {
 
     private static final Map<String, AuthService> AUTH_SERVICES_MAP = new ConcurrentHashMap<>();
 
+    private static final String[] ALLOWED_SCHEMES = new String[]{"http", "https"};
+
+    private static final UrlValidator URL_VALIDATOR = new UrlValidator(ALLOWED_SCHEMES);
+
     public static boolean obtainDeliveryAgreement(final CloseableHttpClient httpClient,
         final String targetUrl,
         final String requestOrigin) {
 
         LogUtils.info(log, "obtain webhook delivery agreement for url: {}", targetUrl);
 
+        if (isInvalidUrl(targetUrl)) {
+            LogUtils.error(log, "Target url is invalid url: {}", targetUrl);
+            return false;
+        }
+
         final HttpOptions builder = new HttpOptions(targetUrl);
         builder.addHeader(REQUEST_ORIGIN_HEADER, requestOrigin);
 
@@ -73,6 +83,10 @@ public class WebhookUtil {
         return true;
     }
 
+    private static boolean isInvalidUrl(String targetUrl) {
+        return !URL_VALIDATOR.isValid(targetUrl);
+    }
+
     public static void setWebhookHeaders(final HttpPost builder,
         final String contentType,
         final String requestOrigin,
diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/WebhookUtilTest.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/WebhookUtilTest.java
index 1e38a6bf1..777467e9a 100644
--- a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/WebhookUtilTest.java
+++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/WebhookUtilTest.java
@@ -54,11 +54,23 @@ public class WebhookUtilTest {
 
             // abnormal case
             Mockito.when(httpClient2.execute(any())).thenThrow(new RuntimeException());
-            Assertions.assertTrue(WebhookUtil.obtainDeliveryAgreement(httpClient2, "xxx", "*"),
+            Assertions.assertTrue(WebhookUtil.obtainDeliveryAgreement(httpClient2, "https://eventmesh.apache.org", "*"),
                 "when throw exception ,default return true");
         }
     }
 
+    @Test
+    public void testObtainDeliveryAgreementWithInvalidTargetUrl() throws Exception {
+        try (CloseableHttpClient httpClient = mock(CloseableHttpClient.class);
+            CloseableHttpResponse response = mock(CloseableHttpResponse.class)) {
+            Mockito.when(response.getLastHeader("WebHook-Allowed-Origin"))
+                .thenReturn(new BasicHeader("WebHook-Allowed-Origin", "*"));
+            Mockito.when(httpClient.execute(any())).thenReturn(response);
+            Assertions.assertFalse(WebhookUtil.obtainDeliveryAgreement(httpClient, "ftp://eventmesh.apache.org", "*"),
+                "when target url is invalid, return false");
+        }
+    }
+
     @Test
     public void testSetWebhookHeaders() {
         final String authType = "auth-http-basic";


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@eventmesh.apache.org
For additional commands, e-mail: commits-help@eventmesh.apache.org